У меня есть приложение, в котором я хотел бы, чтобы пользователь мог запускать задачу по времени, и когда время истечет, иерархия навигации должна появиться и вернуть пользователя. У меня есть код, который ~ работает, но мне не нравится запах кода. Это правильный подход к чему-то вроде этого?
class SimpleTimerManager: ObservableObject {
@Published var elapsedSeconds: Double = 0.0
private(set) var timer = Timer()
func start() {
timer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true) {_ in
self.elapsedSeconds += 0.01
}
}
func stop() {
timer.invalidate()
elapsedSeconds = 0.0
}
}
struct ContentView: View {
@ObservedObject var timerManager = SimpleTimerManager()
var body: some View {
NavigationView {
NavigationLink(destination: CountDownIntervalView(
timerManager: timerManager, length: 5.0
)) {
Text("Start the timer!")
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
struct CountDownIntervalView: View {
@ObservedObject var timerManager: SimpleTimerManager
var length: Double
@Environment(\.presentationMode) var mode: Binding<PresentationMode>
var interval: Double {
let interval = length - self.timerManager.elapsedSeconds
if interval <= 0 {
self.mode.wrappedValue.dismiss()
self.timerManager.stop()
}
return interval
}
var body: some View {
VStack {
Text("Time remaining: \(String(format: "%.2f", interval))")
Button(action: {
self.mode.wrappedValue.dismiss()
self.timerManager.stop()
}) {
Text("Quit early!")
}
}
.navigationBarBackButtonHidden(true)
.onAppear(perform: {
self.timerManager.start()
})
}
}
У меня есть настраиваемая кнопка возврата, которую я бы хотел сохранить. Меня больше всего беспокоит то, что мне кажется неправильным иметь код, который останавливает таймер и выводит навигацию внутри вычисляемого свойства. Я бы предпочел что-то вроде
Text("\(interval)").onReceive(timerManager.timer, perform: { _ in
if self.interval <= 0 {
self.mode.wrappedValue.dismiss()
self.timerManager.stop()
}
})
внутри CountDownIntervalView
, но это приводит к ошибке компилятора - Unable to infer complex closure return type; add explicit type to disambiguate
- и, честно говоря, я не уверен, что этот подход также имеет смысл (добавление кода, который условно выводит навигацию на часть пользовательского интерфейса) . Как лучше всего подойти к этой проблеме?
Спасибо за любые мысли.