3

[Xcode 14.1, iOS 16.1] I have a NavigationStack with a navigationTitle and a TabView with 2 Views. Each View has a ScrollView (see image below):

NavigationStack and TabView problem image

When I tap on Tab1 (#1 in red on the image above), then swipe up, the behavior is as expected (#2), i.e. the big navigationTitle move to the center, and my view passes below and becomes blurry. Perfect. However, when I tap ton Tab2 (#3) and then swipe up (#4), the big title stays big, and the view doesn't become blurry. Then I tap on Tab1 again (#5) and it works as expected.

Please help!

Here is my code:

ContentView:

import SwiftUI

struct ContentView: View {
   
   @State private var selection: Tab = .tab1
   enum Tab {
      case tab1
      case tab2
   }
   @State private var mainTitle = "Tab1"
   
    var body: some View {
        
       NavigationStack {
          
          TabView(selection: $selection) {
             
             Tab1(mainTitle: $mainTitle)
                 .tabItem {
                     Label("Tab1", systemImage: "wrench.adjustable.fill")
                 }
                 .tag(Tab.tab1)
             
             Tab2(mainTitle: $mainTitle)
                 .tabItem {
                     Label("Tab2", systemImage: "wrench.adjustable.fill")
                 }
                 .tag(Tab.tab2)
             
          } .navigationTitle(mainTitle)
          
       }
       
    }
}

Tab1:

import SwiftUI

struct Tab1: View {
   @Binding var mainTitle : String
   
    var body: some View {
       ScrollView {

          Text("Text tab 1")
             .padding(.all,100)
             .background(.blue)
       } .onAppear {
          mainTitle = "Tab1"
       }
    }
}

Tab2:

import SwiftUI

struct Tab2: View {
   @Binding var mainTitle : String
   
    var body: some View {
       ScrollView {

          Text("Text tab 2")
             .padding(.all,100)
             .background(.green)
       } .onAppear {
          mainTitle = "Tab2"
       }
    }
}

I tried a hack that is supposed to fix the transparency bug for Tab bars, but it doesn't work.

.onAppear {
let tabBarAppearance = UITabBarAppearance()
                tabBarAppearance.configureWithOpaqueBackground()
                UITabBar.appearance().scrollEdgeAppearance = tabBarAppearance
}
2
  • Each tab gets its own navigation stack a tab view has to be at the very top of the app. Commented Nov 23, 2022 at 2:44
  • Thank you. I was doing it wrong. Commented Nov 23, 2022 at 18:13

1 Answer 1

9

TabViews are designed to sit at the top of the navigation hierarchy. They're intended to allow users to switch between independent sections of your app at any time.

You would generally put a separate navigation stack within each tab that then handles pushing and popping of views. And then, you can use the navigationTitle modifier to manage the screen's title.

So your structure (which might be split over multiple custom views) should look something like:

TabView {
  NavigationStack {
    ScrollView {
    }
    .navigationTitle("Tab 1")
  }
  .tabItem { Label("Tab1", ...) }
  NavigationStack {
    ScrollView {
    }
    .navigationTitle("Tab 2")
  }
  .tabItem { Label("Tab2", ...) }
}

This structure is by design, to align with Apple's Human Interface Guidelines. It's worth reading the HIG to get a handle on where Apple are coming from, and how working on the same principles can really help your app feel like it belongs on your users' device.

Sign up to request clarification or add additional context in comments.

1 Comment

if i want to "push" new screen from side, that will cover all the TabView, How can I do it with NavigationStack for each Tab?

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.