Как использовать popToRoot с новым навигационным стеком iOS 16 внутри TabView?

Я хотел бы иметь возможность popToRoot из моего первого tabItem (когда я на странице 2 (из первого tabItem) и дважды нажимаю на первый tabItem, когда я на втором tabItem) без необходимости использовать пакет NavigationViewKit и только новый NavigationStack, это возможно ?

Мое решение работает нормально, но я хотел бы избавиться от пакета NavigationViewKit.

Любой хороший совет\пример кода будет оценен по достоинству.

Мой код:

Домашняя страница

      import SwiftUI
import NavigationViewKit

struct Home_V: View {
    @State var tabSelected: Int = 0
    @State private var tappedTwice: Bool = false
    
    // https://designcode.io/swiftui-handbook-tabbar-to-root-view
    var handler: Binding<Int> { Binding(
        get: { tabSelected },
        set: {
            if $0 == tabSelected {
                // print("tabSelected == \(tabSelected)")
                tappedTwice = true
            }
            tabSelected = $0
        }
    )}
    
    // https://github.com/fatbobman/NavigationViewKit
    @Environment(\.navigationManager) var nvmanager
    
    var body: some View {
        TabView(selection: handler) {
            NavigationStack {
                Page1()
                    .onChange(of: tappedTwice, perform: { tappedTwice in
                        guard tappedTwice else { return }
                        if tabSelected == 0 {
                            self.tappedTwice = false
                           nvmanager.wrappedValue.popToRoot(tag:"Page1", animated: true){}
                        }
                    })
            }
            .tabItem {
                Label("_HomeTitle", systemImage: "house")
                    .environment(\.symbolVariants, tabSelected == 0 ? .fill : .none)
            }
            .tag(0)
            .navigationViewStyle(StackNavigationViewStyle())
            
            NavigationStack {
                Page2()
            }
            .tabItem {
                Label("_MessagesTitle", systemImage: "envelope")
                    .environment(\.symbolVariants, tabSelected == 1 ? .fill : .none)
            }
            .tag(1)
            .navigationViewStyle(StackNavigationViewStyle())
            
        }

    }
}

Страница 1

      import SwiftUI
import NavigationViewKit

struct Page1: View {
    var body: some View {
        VStack {
            Text("Page 1")
            NavigationLink {
                Page2()
            } label: {
                Text("Go to Page 2")
            }
        }
        .navigationViewManager(for: "Page1", afterBackDo: {print("Back to Page1")})
    }
}

1 ответ

Я понял!

Вот мой тестовый код:

      import SwiftUI

class NavigationCoordinator: ObservableObject {
    @Published var path = NavigationPath()
    
    func popToRoot() {
        path.removeLast(path.count)
    }
}

struct Test_PopToRoot_NavigationStack: View {
    @State private var tabSelected: Int = 0
    @State private var tappedTwice: Bool = false
    
    @StateObject var navigationCoordinator = NavigationCoordinator()
    @StateObject var navigationCoordinator2 = NavigationCoordinator()
    
    
    // https://designcode.io/swiftui-handbook-tabbar-to-root-view
    var handler: Binding<Int> { Binding(
        get: { tabSelected },
        set: {
            if $0 == tabSelected {
                // print("tabSelected == \(tabSelected)")
                tappedTwice = true
            }
            tabSelected = $0
        }
    )}
    
    var body: some View {
        TabView(selection: handler) {
            NavigationStack(path: $navigationCoordinator.path) {
                VStack {
                    NavigationLink(value: 1) {
                        Test_PopToRoot_Tabview1()
                            .foregroundColor(.black)
                            .onChange(of: tappedTwice, perform: { tappedTwice in
                                guard tappedTwice else { return }
                                if tabSelected == 0 {
                                    self.tappedTwice = false
                                    print("Home tapped twice!!!")
                                    navigationCoordinator.popToRoot()
                                }
                            })
                    }
                }
            }
            .environmentObject(navigationCoordinator)
            .tabItem {
                Label("_HomeTitle", systemImage: "house")
                    .environment(\.symbolVariants, tabSelected == 0 ? .fill : .none)
            }
            .tag(0)
            .navigationViewStyle(StackNavigationViewStyle())
            
            NavigationStack(path: $navigationCoordinator2.path) {
                VStack {
                    NavigationLink(value: 1) {
                        Test_PopToRoot_Tabview2()
                            .foregroundColor(.black)
                            .onChange(of: tappedTwice, perform: { tappedTwice in
                                guard tappedTwice else { return }
                                if tabSelected == 1 {
                                    self.tappedTwice = false
                                    print("2nd Tab tapped twice!!!")
                                    navigationCoordinator2.popToRoot()
                                }
                            })
                    }
                }
            }
            .environmentObject(navigationCoordinator2)
            .tabItem {
                Label("_MessagesTitle", systemImage: "envelope")
                    .environment(\.symbolVariants, tabSelected == 1 ? .fill : .none)
            }
            .tag(1)
            .navigationViewStyle(StackNavigationViewStyle())
        }
    }
}


struct Test_PopToRoot_Tabview1: View {
    var body: some View {
        VStack {
               NavigationLink(value: 2) {
                   Text("Go To Page2")
                       .foregroundColor(.black)
               }
           }
           .navigationDestination(for: Int.self) { i in
               Test_PopToRoot_Page2()
           }
        .navigationTitle(Text("Tabview1"))
    }
}
Другие вопросы по тегам