如何设置多个组合计时器发布者?

时间:2020-12-31 01:01:58

标签: swift swiftui combine

这里我有一个简单的 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
        }
    }
}

1 个答案:

答案 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"),
        ],
      ),
    );
  }
}