如何在 SwiftUI 中动态隐藏导航返回按钮

Posted

技术标签:

【中文标题】如何在 SwiftUI 中动态隐藏导航返回按钮【英文标题】:How to dynamically hide navigation back button in SwiftUI 【发布时间】:2020-05-08 18:50:17 【问题描述】:

我需要在异步操作期间暂时在视图中隐藏后退按钮。 我想阻止用户在操作完成之前离开视图。

可以使用 .navigationBarBackButtonHidden(true)永久隐藏它。 但是,显然用户在这种情况下无法返回,所以他们被卡住了。 我错过了什么?

这是一个人为的例子来演示:

struct TimerTest: View 
    @State var isTimerRunning = false

    var body: some View 
        Button(action:self.startTimer) 
            Text("Start Timer")
        
        .navigationBarBackButtonHidden(isTimerRunning)
        //.navigationBarBackButtonHidden(true) // This does hide it, but then it can't be unhidden.
    

    func startTimer()
    
        self.isTimerRunning = true

        _ = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: false)  timer in
            print("Timer fired!")
            self.isTimerRunning = false
        
    

【问题讨论】:

【参考方案1】:

这是有效的解决方案。后退按钮不能隐藏,它由 bar 管理并归父视图所有,但是可以通过以下方法隐藏整个导航栏。

使用 Xcode 11.4 / ios 13.4 测试

struct ParentView: View 
    @State var isTimerRunning = false
    var body: some View 
        NavigationView 
            VStack 
                NavigationLink("Go", destination: TimerTest(isTimerRunning: $isTimerRunning))
            
            .navigationBarHidden(isTimerRunning)
            .navigationBarTitle("Main")      // << required, at least empty !!
        
    


struct TimerTest: View 
    @Binding var isTimerRunning: Bool

    var body: some View 
        Button(action:self.startTimer) 
            Text("Start Timer")
        
    

    func startTimer()
    
        self.isTimerRunning = true

        _ = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: false)  timer in
            DispatchQueue.main.async       // << required !!
                self.isTimerRunning = false
            
        
    

【讨论】:

非常感谢。很好地抓住了 GUI 更新所需的“主线程”。我的坏那里。但是,在我的“真实”情况下,这不是问题。设置 navigationBarTitle 为我解决了这个问题。如果您出于某种原因不想设置标题,也可以添加一个 navigationBarItem 来解决这个问题。知道为什么需要对 NavBar 进行这些修改才能使其正常工作吗?

以上是关于如何在 SwiftUI 中动态隐藏导航返回按钮的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SwiftUI 中再次初始化 View?

如何从 SwiftUI 中的函数返回按钮?

如何在导航栏中添加返回按钮?

在导航项中隐藏返回文本

SwiftUI 视图之间的导航

Flutter——两种监听导航栏返回按钮的方法