我有一个 iOS 13.5 SwiftUI (macOS 10.15.6) 应用程序,它需要用户在NavigationView
层次结构中导航两个级别才能玩游戏。比赛计时。我想在两个级别都使用自定义后退按钮,但如果我这样做了,第二级的计时器会以一种奇怪的方式中断。如果我放弃第一级的自定义后退按钮并使用系统后退按钮一切正常。这是一个复制问题的最小应用程序:
class SimpleTimerManager: ObservableObject {
@Published var elapsedSeconds: Double = 0.0
private(set) var timer = Timer()
func start() {
print("timer started")
timer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true) {_ in
if (Int(self.elapsedSeconds * 100) % 100 == 0) { print ("\(self.elapsedSeconds)") }
self.elapsedSeconds += 0.01
}
}
func stop() {
timer.invalidate()
elapsedSeconds = 0.0
print("timer stopped")
}
}
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(destination: CountDownIntervalPassThroughView()) {
Text("Start the timer!")
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
struct CountDownIntervalPassThroughView: View {
@Environment(\.presentationMode) var mode: Binding<PresentationMode>
var body: some View {
VStack {
NavigationLink(destination: CountDownIntervalView()) {
Text("One more click...")
}
Button(action: {
self.mode.wrappedValue.dismiss()
print("Going back from CountDownIntervalPassThroughView")
}) {
Text("Go back!")
}
}
.navigationBarBackButtonHidden(true)
}
}
struct CountDownIntervalView: View {
@ObservedObject var timerManager = SimpleTimerManager()
@Environment(\.presentationMode) var mode: Binding<PresentationMode>
var interval: Double { 10.0 - self.timerManager.elapsedSeconds }
var body: some View {
VStack {
Text("Time remaining: \(String(format: "%.2f", interval))")
.onReceive(timerManager.$elapsedSeconds) { _ in
print("\(self.interval)")
if self.interval <= 0 {
print("timer auto stop")
self.timerManager.stop()
self.mode.wrappedValue.dismiss()
}
}
Button(action: {
print("timer manual stop")
self.timerManager.stop()
self.mode.wrappedValue.dismiss()
}) {
Text("Quit early!")
}
}
.onAppear(perform: {
self.timerManager.start()
})
.navigationBarBackButtonHidden(true)
}
}
实际上,使用此示例代码,即使我重新使用系统也会出现一些奇怪的行为,尽管我的完整应用程序没有这个问题,而且我看不出任何可以解释原因的差异。但是 - 目前我想关注为什么这段代码会因多级自定义后退按钮而中断。
在此先感谢您对此的任何想法...