10

In a SwiftUI 2 navigation bar I have a list with multiple sections. All sections have a header, however I want the top section to never be closed and the elements will never be hidden. This is ask for only the first header and also want that the disclosure indicator / collapsing symbol to be gone or hidden.

Can this be done in SwiftUI 2? I want to have this to work in macOS and iPadOS.

@State var agendaViews: [String] = ["Agenda", "Client", "Next Client"]
@State var treatmentViews: [String] = ["Treatment", "Products", "Merchandising"]
@State var selectionAgenda: String?

var body: some View {
    NavigationView {
        VStack {
            List(selection: $selectionAgenda) {
                Section(header: ListHeader()) {    // <<<<<<< For this section no Close Icon and No way to close this section.
                    ForEach(agendaViews, id: \.self) { string in
                        NavigationLink(destination: DetailsView(test: string)) {
                            Text(string)
                        }
                    }
                }
                Section(header: ListHeader2(), footer: ListFooter2()) {
                    ForEach(treatmentViews, id: \.self) { string in
                        NavigationLink(destination: DetailsView2(test: string)) {
                            Text(string)
                        }
                    }
                }
            }.listStyle(SidebarListStyle())
    }
  }
}

struct ListHeader1: View {
  var body: some View {
      HStack {
        Image(systemName: "calendar")
        Text("Agenda")
      }
    }
  }
  struct ListHeader2: View {
  var body: some View {
     HStack {
        Image(systemName: "person.3")
        Text("Clienten")
     }
    }
   }

   struct ListFooter3: View {
     var body: some View {
       Text("===")
     }
   }

I hope my question is clear. As always thank you very much.

Some image added to show that a section header has a close and open button.

Open & Close

4
  • There is no close buttons for provided code snapshot (sections are not disclosable). At least as tested with Xcode 12 / iPadOS 14. Would you provide real testable code? Commented Jul 23, 2020 at 13:50
  • This is the code, the buttons to open and close in the sections are made by iPadOS. And as you can see I can open and close the sections. Not sure what you meant to say otherwise. Commented Jul 23, 2020 at 14:29
  • I still can’t solve this. Using XCode 12 b4. Anyone? Commented Aug 17, 2020 at 13:38
  • If you don't care about all sections being non-collapsible, the answer here solved the issue for me. stackoverflow.com/questions/64350979/… Commented Jul 6, 2021 at 11:41

3 Answers 3

9

Use the collapsible view modifier for the Section. Your first section would become:

Section(header: ListHeader()) {
    ForEach(agendaViews, id: \.self) { string in
        NavigationLink(destination: DetailsView(test: string)) {
            Text(string)
        }
    }
}
.collapsible(false)
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your response. Just replying to myself. I do get the notification "'collapsible' is unavailable in iOS". Shouldn't that be iPadOS? Then I have the next side question. How can I create an 100% iPadOS Project with a iPadOS SDK in Xcode 12?
Whoops, yeah, I thought this was available on all platforms, but it's macOS-specific. As of right now, I don't think there's a way to create a new iPadOS-specific project. You just need to start with the iOS project template.
On iOS you can make change the list style toInsetGroupedListStyle() (to disable collapsing completely) on macOS you use .collapsible(false) for specific sections.
2

Not really 'the' answer but for now a solution to my issue. Still if someone knows a better solution please correct me.

I did change the following in the code:

var body: some View {
        VStack  {
            List(selection: $selectionAgenda) {
                ListHeader1()
                ForEach(agendaViews, id: \.self) { string in
                    NavigationLink(destination: DetailsView2(test: string)) {
                        Text(string)
                    }
                }
                Section(header: ListHeader2(), footer: ListFooter2()) {
                    ForEach(treatmentViews, id: \.self) { string in
                        NavigationLink(destination: DetailsView2(test: string)) {
                            Text(string)
                        }

                    }

                }
            }
            .listStyle(SidebarListStyle())
       }
   }


struct ListHeader1: View {
    var body: some View {
        HStack {
            Image(systemName: "calendar")
            Text("Agenda")
        }.font(.title2)
    }
}

struct ListHeader2: View {
    var body: some View {
        HStack {
            Image(systemName: "person.3")
            Text("Clienten")
        }.font(.title2)
    }
}

In text, I did remove only the first section of the list and replace it with just the Header View, and Voila, on the iPad it looks good for the moment.

Comments

2

This collapsing feature is purely based on what SwiftUI thinks the List for the list should be.

At least to my knowledge, this happens with Sections inside of Lists.

I've been messing around with this because I ran into the same dilemma so I put together a little example app.

Screenshot of ListStyle Example App

import SwiftUI
struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack {
                List {
                    Section {
                        Text(".automatic")
                    }
                }
                .listStyle(.automatic)
                List {
                    Section {
                        Text(".sidebar")
                    }
                }
                .listStyle(.sidebar)
                List {
                    Section {
                        Text(".plain")
                    }
                }
                .listStyle(.plain)
                List {
                    Section {
                        Text(".grouped")
                    }
                }
                .listStyle(.grouped)
                List {
                    Section {
                        Text(".inset")
                    }
                }
                .listStyle(.inset)
                 List {
                     Section {
                         Text(".insetGrouped")
                     }
                 }
                .listStyle(.insetGrouped)
            }
            .navigationTitle("ListStyle Examples")
        }
    }
}

Everything apart from .automatic and .sidebar seems to remove the collapsing arrows :)

2 Comments

Only .sidebar worked for me. Since i wanted the extra top space to be removed (seems to be used for animating and sticky header). But then, i do not want sections to be collapsed by the user.
On Xcode 15 beta 2, arrows no longer show up.

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.