我不确定我是否正确地使用了它,但情况如下:
我有一个观点:
struct TimerView: View {
@State private var numberOfVideos: Int
@State private var time = ""
private let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
init(numberOfVideos: Int) {
_numberOfVideos = State(initialValue: numberOfVideos)
}
var body: some View {
Text(time)
.onReceive(timer) { _ in
// it is called every second
time = "00:00"
}
ReportView(numberOfVideos: $numberOfVideos)
}
}
struct ReportView: View {
@Binding private var numberOfVideos: Int
init(numberOfVideos: Binding<Int>) {
// ❌ this is called every second, I don't want it.
self._numberOfVideos = numberOfVideos
}
var body: some View {
Text(String(numberOfVideos))
}
}
使用方法:
TimerView(numberOfVideos: 5)
每秒示例化ReportView
这不是我需要的。我如何解决这个问题?
2条答案
按热度按时间tvz2xvvm1#
在单独的视图中移动计时器逻辑,如下所示:
o4tp2gmn2#
问题是您将
numberOfVideos
存储为ReportView
上的Binding
。您应该只使用
Binding
将可变状态注入到子视图中,当可变状态从视图内部或外部更改时,您希望重新绘制子视图。因为你永远不会从
ReportView
内部改变numberOfVideos
,所以你应该把它存储为一个不可变的属性。如果TimerView
会更新numberOfVideos
,那就会重新绘制整个TimerView
,从而也会用更新后的数字创建一个新的ReportView
。这可以确保每次在
TimerView
上更新time
时不会重新创建ReportView
。