这里我有一个简单的 SwiftUI 项目,它有两个计时器发布器,它们分别设置为每 1 秒和 2 秒触发一次。
预期行为是第一个标签每秒更新一次,第二个标签每 2 秒更新一次。然而,实际发生的只是第一个标签每秒更新一次,而第二个标签无限期地保持为 0。
我知道可以通过简单地为这些计时器实例创建新变量来使用 Timer.scheduledTimer(withTimeInterval:)
来创建多个计时器,但对于这些发布者来说,它的工作方式似乎不同。
如何让两个定时器都工作?
import SwiftUI
struct ContentView: View {
@State private var counter1 = 0
@State private var counter2 = 0
let timer1 = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
let timer2 = Timer.publish(every: 2, on: .main, in: .common).autoconnect()
var body: some View {
VStack(spacing: 30) {
Text(String(counter1))
.frame(width: 50, height: 20)
Text(String(counter2))
.frame(width: 50, height: 20)
}
.padding()
.onReceive(timer1) {_ in
counter1 += 1
}
.onReceive(timer2) {_ in
counter2 += 2
}
}
}
答案 0 :(得分:2)
在 SwiftUI 中,您的视图是一个临时结构。即系统一直在重新制作视图并丢弃旧的视图。因此,视图不应持有对计时器的引用(您将一直创建新计时器并丢弃旧计时器)。创建一个 viewModel 并将值存储在那里。通常,不要在视图中存储不在属性包装器中或通过初始化程序传入的内容。
class MainScreenPortraitPageUI extends StatefulWidget {
@override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreenPortraitPageUI> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("App title goes here")),
body: Column(
children: [
Text('I want this widget to be drawn after some delay),
Text("Second widget"),
Text("Third widget"),
],
),
);
}
}