在SwiftUI视图中结合onChange和onAppear事件? [英] Combine onChange and onAppear events in SwiftUI view?
问题描述
我正在使用 onChange
修饰符在视图上观察属性.但是,我也希望同一段代码也可以在初始值上运行,因为有时数据会注入到初始化程序中,或者稍后异步加载.
I'm observe a property on a view using the onChange
modifier. However, I'd also like the same piece of code to run on the initial value as well because sometimes the data is injected in the initializer or asynchronously loaded later.
例如,我有一个注入模型的视图.有时,此模型中包含数据以开始(例如预览),或者从网络中异步检索.
For example, I have a view that gets a model injected. Sometimes this model has data in it to begin with (like previews), or is asynchronously retrieved from the network.
class MyModel: ObservableObject {
@Published var counter = 0
}
struct ContentView: View {
@ObservedObject var model: MyModel
var body: some View {
VStack {
Text("Counter: \(model.counter)")
Button("Increment") { model.counter += 1 }
}
.onChange(of: model.counter, perform: someLogic)
.onAppear { someLogic(counter: model.counter) }
}
private func someLogic(counter: Int) {
print("onAppear: \(counter)")
}
}
在 onAppear
和 onChange
情况下,我都想运行 someLogic(counter:)
.有没有更好的方法来获得这种行为或将它们结合起来?
In both onAppear
and onChange
cases, I'd like to run someLogic(counter:)
. Is there a better way to get this behaviour or combine them?
推荐答案
您可能需要 onReceive
.代替:
.onChange(of: model.counter, perform: someLogic)
.onAppear { someLogic(counter: model.counter) }
您可以这样做:
.onReceive(model.$counter, perform: someLogic)
onChange
和 onReceive
之间的区别在于,后者在视图初始化时也会触发.
The difference between onChange
and onReceive
is that the latter also fires when the view is initialised.
onChange
如果您仔细查看 onChange
,您会发现它仅在值更改时才执行操作(而在视图中不会发生这种情况)已初始化).
If you take a closer look at onChange
, you'll see that it performs an action only when a value changes (and this doesn't happen when a view is initialised).
/// Adds a modifier for this view that fires an action when a specific
/// value changes.
/// ...
@inlinable public func onChange<V>(of value: V, perform action: @escaping (V) -> Void) -> some View where V : Equatable
onReceive
但是,在初始化视图时,计数器的发布者也会发出该值.这将使 onReceive
执行作为参数传递的操作.
However, the counter's publisher will emit the value also when a view is initialised. This will make onReceive
perform an action passed as a parameter.
/// Adds an action to perform when this view detects data emitted by the
/// given publisher.
/// ...
@inlinable public func onReceive<P>(_ publisher: P, perform action: @escaping (P.Output) -> Void) -> some View where P : Publisher, P.Failure == Never
请注意, onReceive
不是等效的 onChange
+ onAppear
onAppear
,但是在某些情况下,视图可能会在不触发 onAppear
的情况下再次初始化.
onAppear
is called when a view appears but in some cases a view may be initialised again without firing onAppear
.
这篇关于在SwiftUI视图中结合onChange和onAppear事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!