skip to Main Content

I’m working with SwiftUI’s Navigation Stack and Tab Bar/Tab Bar Style and before setting the tab bar style to page everything works as expected. Here is an example:

Code:

struct TabsView: View {
    enum Tab {
        case home
    }
    
    @State private var selectedTab: Tab = .home
    
    var body: some View {
        TabView(selection: $selectedTab) {
            NavigationStack {
                ScrollView {
                    Text("Home Screen")
                        .navigationTitle("Home")
                        .navigationBarTitleDisplayMode(.inline)
                        .toolbar(.visible, for: .navigationBar)
                        .toolbarBackground(.visible, for: .navigationBar)
                }
            }
            .tabItem {
                Image(systemName: "square")
            }
            .tag(Tab.home)
        }
    }
}

Screenshot:
enter image description here

But as soon as I add the .tabViewStyle(.page), it breaks. It does not take up the full height as expected for the navigation bar. Also, the text is now hidden behind the navigation bar:

Code:

struct TabsView: View {
    enum Tab {
        case home
    }
    
    @State private var selectedTab: Tab = .home
    
    var body: some View {
        TabView(selection: $selectedTab) {
            NavigationStack {
                ScrollView {
                    Text("Home Screen")
                        .navigationTitle("Home")
                        .navigationBarTitleDisplayMode(.inline)
                        .toolbar(.visible, for: .navigationBar)
                        .toolbarBackground(.visible, for: .navigationBar)
                }
            }
            .tabItem {
                Image(systemName: "square")
            }
            .tag(Tab.home)
        }
        .tabViewStyle(.page)
    }
}

Screenshot:
enter image description here

2

Answers


  1. The issue you’re encountering is due to the fact that the NavigationStack modifier is not compatible with the .tabViewStyle(.page) modifier. When you use .tabViewStyle(.page), SwiftUI creates a new navigation stack for each tab, which means that the NavigationStack modifier is not needed.

    To fix this issue, you can remove the NavigationStack modifier and use the NavigationView modifier instead.

    Like:

    struct TabsView: View {
    enum Tab {
        case home
    }
    
    @State private var selectedTab: Tab = .home
    
    var body: some View {
        TabView(selection: $selectedTab) {
            NavigationView {
                ScrollView {
                    Text("Home Screen")
                        .navigationTitle("Home")
                        .navigationBarTitleDisplayMode(.inline)
                        .toolbar(.visible, for: .navigationBar)
                        .toolbarBackground(.visible, for: .navigationBar)
                }
            }
            .tabItem {
                Image(systemName: "square")
            }
            .tag(Tab.home)
        }
        .tabViewStyle(.page)
    }
    

    Simulator

    Login or Signup to reply.
  2. If you don’t have the Pages tab style (.tabViewStyle(.page)), you have both top and bottom safe areas covered as shown below.

    enter image description here

    So Color.red.ignoresSafeArea() is completely covered in the code below.

    import SwiftUI
    
    struct ContentView1: View {
        @State private var selectedTab: Tab = .home
        
        var body: some View {
            ZStack {
                Color.red.ignoresSafeArea()
                TabView(selection: $selectedTab) {
                    NavigationStack {
                        ScrollView {
                            Text("Home Screen")
                                .navigationTitle("Home")
                                .navigationBarTitleDisplayMode(.inline)
                                .toolbar(.visible, for: .navigationBar)
                                .toolbarBackground(.visible, for: .navigationBar)
                        }
                    }
                    .tabItem {
                        Image(systemName: "square")
                    }
                    .tag(Tab.home)
                }
                //.tabViewStyle(.page)
            }
        }
    }
    

    If you have the Pages tab style (.tabViewStyle(.page)), on the other hand, you lose both top and bottom safe areas as shown in the following pictures.

    enter image description here

    import SwiftUI
    
    struct ContentView2: View {
        @State private var selectedTab: Tab = .home
        
        var body: some View {
            ZStack {
                Color.red.ignoresSafeArea()
                TabView(selection: $selectedTab) {
                    NavigationStack {
                        ScrollView {
                            Text("Home Screen")
                                .navigationTitle("Home")
                                .navigationBarTitleDisplayMode(.inline)
                                .toolbar(.visible, for: .navigationBar)
                                .toolbarBackground(.visible, for: .navigationBar)
                        }
                    }
                    .tabItem {
                        Image(systemName: "square")
                    }
                    .tag(Tab.home)
                }
                .tabViewStyle(.page)
            }
        }
    }
    

    So I have a similar layer whose color is close to that of the bottom safe area above TabView in the following.

    import SwiftUI
    
    struct ContentView3: View {
        @State private var selectedTab: Tab = .home
        
        var body: some View {
            ZStack {
                Color.black.opacity(0.03).ignoresSafeArea(edges: .top)
                TabView(selection: $selectedTab) {
                    NavigationStack {
                        ScrollView {
                            Text("Home Screen")
                                .navigationTitle("Home")
                                .navigationBarTitleDisplayMode(.inline)
                                .toolbar(.visible, for: .navigationBar)
                                .toolbarBackground(.visible, for: .navigationBar)
                        }
                    }
                    .tabItem {
                        Image(systemName: "square")
                    }
                    .tag(Tab.home)
                }
                .tabViewStyle(.page)
            }
        }
    }
    

    The following picture shows the result.

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search