Make List Sections non-collapsible in SwiftUI when embedded into a NavigationView SwiftUI
Asked Answered
F

5

20

When I embed a List grouped into Sections into a NavigationView the section headers become collapsible. I'd like to keep them non-collapsible, just like when the List is not embedded into the NavigationView.

My current code (with the NavigationView):

import SwiftUI

struct MyGroup {
    var name:String, items:[String]
}

struct ContentView: View {
    var groups : [MyGroup] = [
        .init(name: "Animals", items: ["πŸ•","🐩","πŸ‚","πŸ„","🐈","🦩","🐿","πŸ‡"]),
        .init(name: "Vehicles", items: ["πŸš•","πŸš—","πŸšƒ","πŸš‚","🚟","🚀","πŸ›₯","⛡️"])]
    
    var body: some View {
        NavigationView {
            VStack {
                List {
                    ForEach(groups, id: \.self.name) { group in
                        Section(header: Text(group.name)) {
                            ForEach(group.items, id:\.self) { item in
                                Text(item)
                            }
                        }
                    }
                }
            }.navigationTitle("collections")
        }
    }
}

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

list with collapsible sections

Frontal answered 14/10, 2020 at 10:4 Comment(2)
As of today it is not possible in iOS. Not even via UIKit. It is only possible with .collapsible(false) on macOS. File a bug with Apple if you want this to change in the future. – Keratin
Putting the List inside the VStack makes it collapsable. – Sogdian
O
45

It is default style applied, you can make it explicitly set for List like below (tested with Xcode 12 / iOS 14)

demo

    List {
        ForEach(groups, id: \.self.name) { group in
            Section(header: Text(group.name)) {
                ForEach(group.items, id:\.self) { item in
                    Text(item)
                }
            }
        }
    }.listStyle(InsetGroupedListStyle()) // or GroupedListStyle
Otoplasty answered 14/10, 2020 at 10:40 Comment(3)
This is not working if the list is embedded in a NavigationView – Keratin
@Keratin It works fine for list embedded in NavigationView. I verified in XCode 13.2 and iOS 15.2. – Hayott
Works for me, Xcode 14.1 (14B47b) – Pilfer
C
8

As of iOS 17, Sections are no longer collapsible (on Xcode 15b2).

To enable collapse/expand behavior:

public init(isExpanded: Binding<Bool>, @ViewBuilder content: () -> Content, @ViewBuilder header: () -> Parent)
Cohort answered 16/7, 2023 at 16:27 Comment(1)
Thanks for pointing that out. Will be really hard to find out why its not working anymore. – Potentilla
S
3

Just using the SidebarListStyle in listStyle modifier

.listStyle(SidebarListStyle())
Staley answered 28/6, 2021 at 6:30 Comment(2)
This is not working if the list is embedded in a NavigationView – Keratin
This is funny because using .sidebar doesnt make it work, but it does what i want (remove the extra top space probably used for animation scrolling in grouping section headers) – Stevana
O
3

In case you're stumbling on this... The issue doesn't have anything to do with being embedded in a NavigationView as the OP and @Danial mentioned. It's because it's embedded in the the VStack at the first level of the NavigationView in the example code. Seems like a SwiftUI bug to me.

Octofoil answered 17/2, 2022 at 2:54 Comment(0)
S
1

I just came across the same problem and none of the suggested solutions worked for me. And contrary to some comments, this is indeed related to Lists embedded inside NavigationViews as I could reproduce the problem even after removing my VStack. The only solution that worked for me was setting the navigationViewStyle to stack:

.navigationViewStyle(StackNavigationViewStyle())
Striate answered 30/3, 2023 at 9:37 Comment(0)

© 2022 - 2025 β€” McMap. All rights reserved.