Search code examples
iosswiftuiswiftui-navigationlinkswiftui-navigationviewswiftui-tabview

SwiftUI TabView inside a NavigationView


So I know it's not really encouraged to put a TabView inside a NavigationView and that you're supposed to do it the other way around. But the way I want my app I don't really see how I can have it another way...

So I have a login screen in which a user inputs their username, then only once I verify that everything is okay with username I wanna bring them over to a TabView(the search button is a navlink) I don't really see any other way to implement this but the problem is with my implementation is once I switch tabs in the tab view, the navigation title doesn't seem to change, and there also doesn't seem to be a navigation bar because when I scroll the old NavigationTitle gets drawn over by a Text View I have.

I'm not sure if adding code would help in this case because it seems this is just kind of a problem with TabViews inside NavigationViews but if someone wants me to show some code I can add an edit with it. I was just wondering if anyone had any ideas for how I could fix something like this or some other way to implement this? Text View blocking NavigationView

Login Screen

Edit:

struct ContentView: View {
    var body: some View {
        NavigationView{
            NavigationLink{
                TabView{
                    ScrollView{
                        Text("Some view")
                    }
                    .tabItem{
                        Text("New View")
                    }
                    ScrollView{
                        Text("Another view")
                    }
                    .tabItem{
                        Text("Another view")
                    }
                }
            } label: {
                Text("Go to new view!")
            }
            
        }
    }
}

Solution

  • It is perfectly fine to have TabView() inside a NavigationView. Every time we switch between pages in any app, the navigating is mostly expected, so almost every view is inside the NavigtionView for this reason.

    You can achieve this design with something like this (see the bottom images also):

    struct LoginDemo: View {
      @State var username = ""
      var body: some View {
        NavigationView {
            VStack {
                TextField("Enter your user name", text: $username)
                    .font(.headline)
                    .multilineTextAlignment(.center)
                    .frame(width: 300)
                    .border(.black)
                NavigationLink {
                    GotoTabView()
                } label: {
                    Text("search")
                }
                .disabled(username == "Admin" ? false : true)
            }
        }
        .navigationTitle("Hey It's Nav View")
      }
    }
    struct GotoTabView: View {
      @State var temp = "status"
      @State var selection = "view1"
      var body: some View {
        TabView(selection: $selection) {
            Image("Swift")
                .resizable()
                .frame(width: 300, height: 300)
                .tabItem {
                    Text("view 1")
                }
                .tag("view1")
            Image("Swift")
                .resizable()
                .frame(width: 500, height: 500)
                .tabItem {
                    Text("view 2")
                }
                .tag("view2")
        }
        .onChange(of: selection){ _ in
            if selection == "view1" {
                temp = "status"
            }
            else {
                temp = "hero"
            }
        }
        .toolbar{
            ToolbarItem(placement: .principal) {
                Text(temp)
            }
        }
      }
    } 
    

    NavigationView:

    enter image description here

    TabView:

    enter image description here

    enter image description here