Foriger
Foriger

Reputation: 459

SwiftUI - Sheet presented from tab view pops to root view of a tab

I need to have a sheet which when closed needs to return to the same view from which is opened and also transfer some information. Unfortunately for some reason the view is poped out when sheet is presented and the logic is broken. Here is MVP of the code:

@main
struct SmallApplication: App {
    var body: some Scene {
        WindowGroup {
            NavigationView {
                TabView {
                    
                    TabbedView1()
                        .tabItem {
                            Label("Tab1", systemImage: "scanner")
                        }
                
                    TabbedView2()
                        .tabItem {
                            Label("Tab2", systemImage: "person")
                        }
                
                }

            }
        }
    }
}

struct TabbedView1: View {
    var body: some View {
        Text("TabbedView1")
            .padding()
    }
}

struct TabbedView2: View {
    var body: some View {
        
        VStack{
            Text("TabbedView2")
            NavigationLink(
                "Go To View 3",
                destination: View3()
            )
        }
    }
}


struct View3: View {
    @State var presentSheet = false
    
    var body: some View {
        Button {
            presentSheet = true
        } label: {
            Text("Click me")
        }.sheet(isPresented: $presentSheet, onDismiss: nil) {
            View4()
        }

    }
}


struct View4: View {
    var body: some View {
        VStack {
            Text("Pull down the sheet and see the result")
        }
    }
}

When you pull down the sheet it pops Tab2 to TabbedView2 instead of View. My question is why and how I can avoid that?

This happens only on iOS 15 but not on iOS 14.7 where everything works fine. I use TabView inside NavigationView because this is the way to hide tab view in Detail View when needed.

Another option, that I'm having is to use fullScreenCover modifier (which works fine), but I prefer to use sheet for this task.

Edit: If you put application with opened View3 on background, when opened TabbedView2 is presented, which makes the problem really worse.

Upvotes: 1

Views: 1494

Answers (2)

ChrisR
ChrisR

Reputation: 12125

Apple/SwiftUI doesn't want to have Tabs enclosed in a NavigationView, because the Tabs should always be visible:

Avoid hiding the tab bar when people navigate to different areas in your app. The tab bar is a global navigation control for your app, so make sure it’s always visible. https://developer.apple.com/design/human-interface-guidelines/ios/bars/tab-bars/

If you don't want this, why not use custom "Tabs" in the bottom at your start page?

@main
struct SmallApplication: App {
    
    @State private var tabSelector = 1
    
    var body: some Scene {
        WindowGroup {
            NavigationView {
                
                Group {
                    if tabSelector == 1 {
                        TabbedView1()
                    } else {
                        TabbedView2()
                    }
                }
                .toolbar {
                    ToolbarItem(placement: .bottomBar) {
                        Button {
                            tabSelector = 1
                        } label: {
                            Label("Tab1", systemImage: "scanner")
                        }
                    }
                    ToolbarItem(placement: .bottomBar) {
                        Button {
                            tabSelector = 2
                        } label: {
                            Label("Tab2", systemImage: "person")
                        }
                    }
                }
            }
        }
    }
}

Upvotes: 4

MoLoW
MoLoW

Reputation: 195

This should solve your issue. I have created two NavigationViews, one for each tab. See code below.

struct SmallApplication: App {
    var body: some Scene {
        WindowGroup {
            
                TabView {
                    NavigationView {
                        TabbedView1()}
                        .tabItem {
                            Label("Tab1", systemImage: "scanner")
                        }
                    
                    NavigationView {
                        TabbedView2()}
                        .tabItem {
                            Label("Tab2", systemImage: "person")
                        }
            }
        }
    }
}

Upvotes: 0

Related Questions