【问题标题】:Reset NagivationView stack in TabView在 TabView 中重置 NagivationView 堆栈
【发布时间】:2021-03-19 17:38:51
【问题描述】:

我有一个带有两个选项卡(选项卡 A 和 B)的选项卡视图。

单击选项卡 A 打开主视图。在该主视图中,有一个指向页面 1 的导航链接。在页面 1 中,还有一个指向页面 2 的链接。 当用户在第 1 页或第 2 页上,并且我点击选项卡 A 时,它不会恢复到主视图。同样,如果用户单击 Tab B,然后再次单击 Tab A,它将返回到第 1 页或第 2 页(无论用户在哪个页面上),而不是主视图。

如何在这两种情况下重置导航堆栈?

谢谢!

【问题讨论】:

  • 很好的问题,但看看一些 SwiftUI 代码也会很有用。

标签: swiftui tabview swiftui-navigationlink


【解决方案1】:

那是因为视图不会被重新渲染。这是实现您的行为的一种可能方法:

您可以对 TabView 使用 ProxyBinding 来检测更改,然后通过更改内部 State 变量来重置 NavigationLink。

struct ContentView: View {
    @State var activeView: Int = 0
    @State var showNavigation: Bool = false
    var body: some View {
        TabView(selection: Binding<Int>(
                    get: {
                        activeView
                    }, set: {
                        activeView = $0
                        showNavigation = false //<< when pressing Tab Bar Reset Navigation View
                    }))
        {
            NavigationView {
                NavigationLink("Click", destination: Text("Page A"), isActive: $showNavigation)
            }
            .tabItem {
                Image(systemName: "1.circle")
                Text("First")
            }
            .tag(0)
            
            Text("Second View")
            .padding()
            .tabItem {
                Image(systemName: "2.circle")
                Text("Second")
            }
            .tag(1)
        }
    }
}

【讨论】:

  • 非常感谢。它绝对能满足我的需要。但是,我现在在导航视图中有 6 个导航链接,每个链接都指向不同的目标视图。当我通过链接导航到一个视图时,再次单击选项卡(重置导航堆栈),然后导航到另一个视图,目的地不是我所期望的。您在上面提供的代码是否以某种方式导致了这种情况?谢谢!
【解决方案2】:

您可以使用 MainView

创建 RootView

    import SwiftUI

    struct RootView: View {
        
        @ObservedObject var viewModel = RootViewModel()
        
        init(){
            viewModel.prepare()
        }
        var body: some View {
            MainView(tab: viewModel.mainTab)
                .id(UUID().uuidString)
        }
    }

创建带有监听器的RootViewModel以进行屏幕更新


    import SwiftUI

    class RootViewModel: ObservableObject{
        
        @Published var mainTab: SelectedTab = .firstTab
        let mainScreenNotification = NSNotification.Name("mainScreenNotification")
        private var observerMain: Any?
        
        
        func prepare(){
            observerMain = NotificationCenter.default.addObserver(forName: mainScreenNotification, object: nil, queue: nil, using: { [unowned self] notification in
                self.mainTab = (notification.userInfo?["selectedTab"])! as! SelectedTab
            })
        }
    }

    enum SelectedTab {
      case firstTab, secondTab
    }
        

运行此命令以从子标签页填充新标签屏幕:


    NotificationCenter.default.post(name: 
       NSNotification.Name("mainScreenNotification"), 
       object: nil,  
       userInfo: ["selectedTab": SelectedTab.firstTab]
    )

【讨论】:

    猜你喜欢
    • 2020-01-06
    • 2019-03-08
    • 2012-09-10
    • 1970-01-01
    • 2019-07-12
    • 2021-07-06
    • 1970-01-01
    • 2021-05-07
    • 1970-01-01
    相关资源
    最近更新 更多