具有PresentationMode的SwiftUI NavigationView在多级导航层次结构中创建错误

时间:2020-07-26 18:37:14

标签: swiftui swiftui-navigationlink swiftui-environment

我有一个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)
  }
}

实际上,使用此示例代码,即使我重新使用系统,也会出现一些奇怪的行为,尽管我的完整应用程序没有此问题,并且看不到任何差异可以解释原因。但是-目前,我想重点介绍为什么此代码会因多级自定义后退按钮而中断。

预先感谢您对此的任何想法...

0 个答案:

没有答案