2

So I've got a NavigationView embedded inside of a TabView that is in the Page View Style. Upon first load the NavigationView will start inside itself, and then once reloaded it shows normally. I am unsure as to what is causing this. And I've made a GIF to better illustrate the problem:

enter image description here

And here is my code:

import SwiftUI

struct ContentView: View {
    
    var body: some View {
        TabView {
            SettingsView()
            EmptyView()
            EmptyView()
            EmptyView()
        }
        .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
    }
}

struct SettingsView: View {
    
    var body: some View {
        NavigationView {
            List {
                Section(header: Text("General")) {
                    NavigationLink(destination: SettingsItem(title: "1")) {
                        Text("1")
                    }
                    
                    NavigationLink(destination: SettingsItem(title: "2")) {
                        Text("2")
                    }
                    
                    NavigationLink(destination: SettingsItem(title: "3")) {
                        Text("3")
                    }
                    
                    NavigationLink(destination: SettingsItem(title: "4")) {
                        Text("4")
                    }
                    
                }
            }
            .listStyle(InsetGroupedListStyle())
            .navigationTitle("Settings")
        }
    }
}

struct SettingsItem: View {
    
    @State var title = "Title"
    
    var body: some View {
        NavigationView {
            List {
                
            }
        }
        .navigationTitle(title)
    }
}

struct EmptyView: View {
    var body: some View {
        ZStack{
            Color.green
            Text("Empty View")
                .padding()
        }
        .border(Color.black, width: 8)
        
    }
}
Mr Duck
  • 115
  • 1
  • 9
  • This is not a [Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example). Please edit your question. – Yrb Aug 19 '21 at 19:32
  • I think that I've managed to make it clearer. Hopefully it makes sense now. – Mr Duck Aug 19 '21 at 21:33
  • Have you found a solution to the wrong positioning of the list under the Navigation Title? Have the same issue ... – Simon Henn Apr 05 '22 at 15:34
  • Unfortunately I was unable to find a solution, in the end I had to completely redo it using HStacks and offsets, and based my solution off [this](https://medium.com/@xtabbas/implementing-snap-carousel-in-swiftui-3ae084504670) code. – Mr Duck Apr 07 '22 at 10:42

1 Answers1

1

Believe it or not, this has nothing to do with the TabView(). This is actually an issue in the SettingsView(). SwiftUI is defaulting to a split view. As a result, you are getting an empty view because you haven't actually navigated to any particular view, with the Settings back button showing. The fix to make this behave as you would expect is to add a .navigationViewStyle(StackNavigationViewStyle() on the NavigationView in SettingsView which forces SettingsView to display as a single view like this:

struct ContentView: View {
    
    var body: some View {
        TabView {
            SettingsView()
            BlankView(color: .green)
            BlankView(color: .blue)
            BlankView(color: .red)
        }
        .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
        
    }
}

struct SettingsView: View {
    
    var body: some View {
        NavigationView {
            List {
                Section(header: Text("General")) {
                    NavigationLink(destination: SettingsItem(title: "1")) {
                        Text("1")
                    }
                    
                    NavigationLink(destination: SettingsItem(title: "2")) {
                        Text("2")
                    }
                    
                    NavigationLink(destination: SettingsItem(title: "3")) {
                        Text("3")
                    }
                    
                    NavigationLink(destination: SettingsItem(title: "4")) {
                        Text("4")
                    }
                    
                }
            }
            .listStyle(InsetGroupedListStyle())
            .navigationTitle("Settings")
        }
        .navigationViewStyle(StackNavigationViewStyle())
    }
}

struct SettingsItem: View {
    
    @State var title = "Title"
    
    var body: some View {
        NavigationView {
            List {
                
            }
        }
        .navigationTitle(title)
    }
}

struct BlankView: View {
    let color: Color
    
    var body: some View {
        ZStack{
            color
            Text("Blank View")
                .padding()
        }
        .border(Color.black, width: 8)
        
    }
}

Also, I edited your code a bit for clarity. EmptyView() is already designated by the system, so I changed it to BlankView() I am not sure why the compiler doesn't have a problem with you naming a struct EmptyView(), but you really shouldn't use that name. I also had the BlankView() show different colors so it was clear you were navigating to separate views.

Yrb
  • 8,103
  • 2
  • 14
  • 44
  • For the most part this works perfectly, but upon first load the title appears to be lower than what it should be. Might be a strange bug. https://imgur.com/a/nZxmLz9 – Mr Duck Aug 21 '21 at 00:20
  • That isn’t an issue with a StackNavigationViewStyle. I use it just this way in production apps and don’t have an issue. It could be an anomaly in your minimal, reproducible example. – Yrb Aug 21 '21 at 00:55
  • I've just put your code into my app, and the anomaly still persists. Is there any way to remove it? Or to know what is causing the issue? – Mr Duck Aug 21 '21 at 01:14
  • I haven’t hit that as an issue. Post that as a new question after researching that. It is frowned upon to try to solve another issue in comments. It makes it difficult for the next person to find an answer. – Yrb Aug 21 '21 at 02:43