29

I'm having an issues with a List inside a NavigationView since iOS 14 update.

Here is a simple breakdown of the code - I've striped everything that doesn't show the issue

struct ContentView: View {
    
    var views = ["Line 1", "Line 2", "Line 3"]
    
    var body: some View {
        
        NavigationView {
            
            VStack {
                
                List {
                    
                    ForEach(views, id: \.self) { view in
                       
                        VStack {
                        Text("\(view)")
                        }
                        .background(Color.red)
                        
                    }
                    
                }
                
            }
            
        }
        
    }
}

This produces the following result:

list inside nav vew

I cant work out why the list is hovering in the center of the navigation view like that. As far as I can tell this should produce a listview that takes up all avaliable space (with the exception of the top where navigationbar would be).

Indeed when run on iOS 13.5 that is the result I get as pictured below:

list in nav view 2

I've had a read through the documentation but cant work out why this behaviour is suddenly happening.

Any help would be greatly appreciated.

Thanks

pawello2222
  • 46,897
  • 22
  • 145
  • 209
swift--help
  • 637
  • 5
  • 15

1 Answers1

64

Problem

It looks like the default styles of a List or NavigationView in iOS 14 may in some cases be different than in iOS 13.

Solution #1 - explicit listStyle

It's no longer always the PlainListStyle (as in iOS 13) but sometimes the InsetGroupedListStyle as well.

You need to explicitly specify the listStyle to PlainListStyle:

.listStyle(PlainListStyle())

Example:

struct ContentView: View {
    var views = ["Line 1", "Line 2", "Line 3"]

    var body: some View {
        NavigationView {
            VStack {
                List {
                    ForEach(views, id: \.self) { view in
                        VStack {
                            Text("\(view)")
                        }
                        .background(Color.red)
                    }
                }
                .listStyle(PlainListStyle()) // <- add here
            }
        }
    }
}

Solution #2 - explicit navigationViewStyle

It looks like the NavigationView's default style can sometimes be the DoubleColumnNavigationViewStyle (even on iPhones).

You can try setting the navigationViewStyle to the StackNavigationViewStyle (as in iOS 13):

.navigationViewStyle(StackNavigationViewStyle())

Example:

struct ContentView: View {
    var views = ["Line 1", "Line 2", "Line 3"]

    var body: some View {
        NavigationView {
            VStack {
                List {
                    ForEach(views, id: \.self) { view in
                        VStack {
                            Text("\(view)")
                        }
                        .background(Color.red)
                    }
                }
            }
        }
        .navigationViewStyle(StackNavigationViewStyle()) // <- add here
    }
}
pawello2222
  • 46,897
  • 22
  • 145
  • 209
  • Hi, thanks for this. I'm not trying to hide the navigation bar. In fact that navigation bar isnt the issue at all. My issues is that the List should be taking up all avaliable space on the screen. But it is only taking up a small central portion on iOS14 as pictures above. I believe the List should be filling the view both horizonally and vertically based on the above code (and it does on ios 13.5) – swift--help Sep 17 '20 at 13:35
  • I have updated my question with more pictures to explain. Thanks again for all the help – swift--help Sep 17 '20 at 13:49
  • 1
    @swift--help Thanks, this is because of the `VStack`. I updated my answer. – pawello2222 Sep 17 '20 at 13:57
  • That does actually produce the desired effect. However, if I wanted something else above the list, for example a search bar, it would cover the entire list without a vstack to seperate them would it not? – swift--help Sep 17 '20 at 14:10
  • 1
    @swift--help Oh, I understand now what you want - please see the updated answer. – pawello2222 Sep 17 '20 at 14:15
  • You are a wizard! Thats what I've been missing. Sorry I've butchered the question! Have a great day! – swift--help Sep 17 '20 at 14:18
  • In my project the inset only seems to happen when using `ForEach` inside `List`. Just using `List` + `.listStyle(PlainListStyle())` does not show the inset. Anyone can confirm this? – koen Sep 21 '20 at 01:22
  • 1
    @koen In the above example, when wrapped in a VStack, both `List` and `List+ForEach` are with insets. Only removing the VStack or setting the `.listStyle` explicitly removes the insets. Unfortunately it's not well documented (yet?) when the `InsetGroupedListStyle` is the default style. – pawello2222 Sep 21 '20 at 07:41
  • @pawello2222 Hmm, I have a VStack with a (custom) `SearchBarView` and a `List`, the default `listStyle`, and it does not show the inset. Maybe the extra view has something to do with it. Anyway, thanks for the pointer to using `PlainListStyle()`. – koen Sep 21 '20 at 12:11
  • thanks a ton for .listStyle(PlainListStyle()) – Abhishek Thapliyal Mar 18 '21 at 09:59
  • .navigationViewStyle(StackNavigationViewStyle()) -> Worked for me Tnx :) – Threadripper Jun 23 '21 at 14:24