2

I need to temporarily hide the Back Button in a view during an asynchronous operation. I want to prevent user from leaving the view before the operation completes.

It's possible to hide it permanently using .navigationBarBackButtonHidden(true). But, then obviously user can't go back in this case, so they are stuck. What am I missing?

Here is a contrived example to demonstrate:

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 Answer 1

2

Here is working solution. Back button cannot be hidden, it is managed by bar and owned by parent view, however it is possible to hide entire navigation bar with below approach.

Tested with Xcode 11.4 / iOS 13.4

demo

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
            }
        }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Awesome thanks. Good catch on the "main thread" needed for GUI updates. My bad there. But, in my "real" situation, this wasn't the problem. Setting the navigationBarTitle is what solved it for me. You can also add a navigationBarItem to solve this if you don't want to set a title for whatever reason. Any idea why making either of these modifications to the NavBar are required for this to work?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.