在SwiftUI视图中结合onChange和onAppear事件? [英] Combine onChange and onAppear events in SwiftUI view?

查看:171
本文介绍了在SwiftUI视图中结合onChange和onAppear事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆