2

I have a SwiftUI list with expandable/collapsable rows. I am attempting to add a Section with a header title at the top of my list. The code prior to adding the section is as follows:

var body: some View {
        List(parentArray, id: \.self, children: \.child) {  item in
                ResultsRowView(circle: item.circle.lowercased(), person: item.person, tally: item.tally)
        }.listStyle(GroupedListStyle())
    }

When I try to add a Section, I am getting funky results. For example, I have tried this:

var body: some View {
        List(parentArray, id: \.self, children: \.child) {  item in
            Section(header: Text("HeaderTitle")) {
                ResultsRowView(circle: item.circle.lowercased(), person: item. person, tally: item.tally)
            }
        }.listStyle(GroupedListStyle())
    }

But that only adds a "HeaderTitle" text element to each of the rows in my list.

Then I tried this:

var body: some View {
        Section(header: Text("HeaderTitle")) {
            List(parentArray, id: \.self, children: \.child) {  item in
                    ResultsRowView(circle: item.circle.lowercased(), person: item.person, tally: item.tally)
            }.listStyle(GroupedListStyle())
        }
    }

But the result of this is that the list disappears entirely and is replaced by the text "HeaderTitle" set in the middle of the screen.

The outcome I am looking for, as you might image, is for a section with a header at the top of my list. Any ideas?

EDIT: my own data would be too cumbersome to include for others to try out. But below is code that follows the same structure as my own, pulled from Paul Hudson's Hacking With Swift website:

import SwiftUI

struct ContentView: View {
    let items: [Bookmark] = [.example1, .example2, .example3]

    var body: some View {
        List(items, children: \.items) { row in
            Image(systemName: row.icon)
            Text(row.name)
                
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct Bookmark: Identifiable {
    let id = UUID()
    let name: String
    let icon: String
    var items: [Bookmark]?

    // some example websites
    static let apple = Bookmark(name: "Apple", icon: "1.circle")
    static let bbc = Bookmark(name: "BBC", icon: "square.and.pencil")
    static let swift = Bookmark(name: "Swift", icon: "bolt.fill")
    static let twitter = Bookmark(name: "Twitter", icon: "mic")

    // some example groups
    static let example1 = Bookmark(name: "Favorites", icon: "star", items: [Bookmark.apple, Bookmark.bbc, Bookmark.swift, Bookmark.twitter])
    static let example2 = Bookmark(name: "Recent", icon: "timer", items: [Bookmark.apple, Bookmark.bbc, Bookmark.swift, Bookmark.twitter])
    static let example3 = Bookmark(name: "Recommended", icon: "hand.thumbsup", items: [Bookmark.apple, Bookmark.bbc, Bookmark.swift, Bookmark.twitter])
}
2
  • 1
    Please provide the minimum code that others can test. Commented Jan 12, 2021 at 21:15
  • Thanks for the prompt. Sample code added. Commented Jan 12, 2021 at 21:35

2 Answers 2

3

You can wrap it in a Form to give it a header:

var body: some View {
    Form {
        Section(header: Text("Header Text")) {
            List(items, children: \.items) { row in
                Image(systemName: row.icon)
                Text(row.name)
            }
        }
    }
}

If you want another style, I'll update this answer if I find any way to maintain the style of the List while displaying the header.

Sign up to request clarification or add additional context in comments.

3 Comments

It worked, thanks! The style of the list appears to be the same, so I'm not certain what you're referring to, unless there is something I'm not seeing. If you'd care to elaborate, I'd be interested. Otherwise, you've already helped me plenty so I'm very grateful.
Nevermind, I see what you mean about the style. I would much prefer the original style that I had, but at least I have the functionality I need. Still, if you know of a way to preserve the style that would be greatly appreciated.
You could recreate the list but make it so that is "sectionable" by modeling the structure of a List in the documentation and then adding whatever fuctionality you need to maintain the style while getting this feature. If you are still having trouble with it later, I may create it myself for personal use and then share it here through an update too.
-1
struct ContentView: View {
    let items: [Bookmark] = [.example1, .example2, .example3]
    
    var body: some View {
        
        List {
            Section(header: Text("Heading")) {
                ForEach(items) { row in
                    HStack {
                        Image(systemName: row.icon)
                        Text(row.name)
                    }
                }
            }
        }.listStyle(GroupedListStyle())
    }
}

Screenshot

Output Screenshot

1 Comment

Thank you for your reply, but this does not address my question. The code you provided does not preserve the child cells from the original example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.