Как динамически скрыть кнопку навигации назад в SwiftUI - PullRequest
2 голосов
/ 08 мая 2020

Мне нужно временно скрыть кнопку «Назад» в представлении во время асинхронной операции. Я хочу запретить пользователю покидать представление до завершения операции.

Это можно скрыть навсегда с помощью .navigationBarBackButtonHidden (true). Но тогда, очевидно, что пользователь не может go вернуться в этом случае, поэтому он застрял. Что мне не хватает?

Вот надуманный пример, чтобы продемонстрировать:

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 Ответ

2 голосов
/ 08 мая 2020

Вот рабочее решение. Кнопка «Назад» не может быть скрыта, она управляется панелью и принадлежит родительскому представлению, однако можно скрыть всю панель навигации с помощью следующего подхода.

Протестировано с 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
            }
        }
    }
}
...