计时器onReceive在NavigationView中不起作用

时间:2020-04-23 03:16:33

标签: swift swiftui

我有以下计时器:

struct ContentView: View {
    @State var timeRemaining = 10
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

    var body: some View {
        NavigationView{
            VStack {
                if(self.timeRemaining > 0) {
                    Text("\(timeRemaining)")
                        .onReceive(timer) { _ in
                            if self.timeRemaining > 0 {
                                self.timeRemaining -= 1
                            }
                    }
                } else {
                    Text("Time is up!")
                }
            }
        }
    }
}

如果我删除了NavigationView视图,计时器将更新并运行,但是像这样不起作用,这是怎么回事,以及如何在NavigationView中更新它?还是有更好的做法?

谢谢

1 个答案:

答案 0 :(得分:3)

最好将观察者附加到非条件视图,例如

Text("\(timeRemaining)")

更新:添加了一些想法(当然,SwiftUI内部组件仅适用于Apple)。

.onReceive必须附加到NavigationView中的持久存在的视图上,原因很可能是在有条件的ViewBuilder和UIKit UINavigationControler周围的NavigationView包装器内部。

如果您删除条件并在NavigationView的VStack中只有一个onReceive的Text视图,那么什么都收不到

如果条件消除后,它附加到timeRemaining上,则所有工作正常(使用Xcode 11.4测试),因为主体中存在状态依赖性。

如果将其附加到常量文本,则正文没有任何变化,即。取决于更改后的状态-{{1}},因此SwiftUI呈现引擎会将主体解释为静态。