期望 SwiftUI DynamicProperty 属性包装器的内部更新触发视图更新是否正确? [英] Is it correct to expect internal updates of a SwiftUI DynamicProperty property wrapper to trigger a view update?

查看:104
本文介绍了期望 SwiftUI DynamicProperty 属性包装器的内部更新触发视图更新是否正确?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建 SwiftUI 支持的自定义属性包装器,这意味着对相应属性值的更改会导致 SwiftUI 视图更新.这是我所拥有的简化版本:

I'm attempting to create a custom property wrapper supported by SwiftUI, meaning that changes to the corresponding properties values would cause an update to the SwiftUI view. Here is a simplified version of what I have:

@propertyWrapper
public struct Foo: DynamicProperty {
    @ObservedObject var observed: SomeObservedObject

    public var wrappedValue: [SomeValue] {
        return observed.value
    }
}

我看到即使我的 ObservedObject 包含在我的自定义属性包装器中,只要:

I see that even if my ObservedObject is contained inside of my custom property wrapper, SwiftUI still catches the changes to SomeObservedObject as long as:

  • 我的属性包装器是一个结构
  • 我的属性包装器符合DynamicProperty

不幸的是,文档很少,我很难判断这是否只是在当前 SwiftUI 实现中不走运.

Unfortunately the docs are sparse and I have a hard time telling if this only works out of luck with the current SwiftUI implementation.

DynamicProperty 的文档(在 Xcode 内,不在线)似乎表明这样的属性是从外部更改导致视图重绘的属性,但不能保证是什么当您使自己的类型符合此协议时会发生这种情况.

The docs of DynamicProperty (within Xcode, not online) seem to indicate that such a property is a property that is changed from the outside causing the view to redraw, but there is no guarantee about what happens when you conform your own types to this protocol.

我可以期待它在未来的 SwiftUI 版本中继续工作吗?

Can I expect this to continue working in future SwiftUI releases?

推荐答案

好吧...这里有另一种方法来获得类似的东西...但作为结构只有 DynamicProperty 包裹在 @状态(强制刷新视图).

Ok... here is alternate approach to get similar thing... but as struct only DynamicProperty wrapped around @State (to force view refresh).

它是一个简单的包装器,但可以通过以下视图刷新来封装任何自定义计算......正如所说的使用仅值类型.

It is simple wrapper but gives possibility to incapsulate any custom calculations with following view refresh... and as said using value-only types.

这是演示(使用 Xcode 11.2/iOS 13.2 测试):

Here is demo (tested with Xcode 11.2 / iOS 13.2):

代码如下:

import SwiftUI

@propertyWrapper
struct Refreshing<Value> : DynamicProperty {
    let storage: State<Value>

    init(wrappedValue value: Value) {
        self.storage = State<Value>(initialValue: value)
    }

    public var wrappedValue: Value {
        get { storage.wrappedValue }

        nonmutating set { self.process(newValue) }
    }

    public var projectedValue: Binding<Value> {
        storage.projectedValue
    }

    private func process(_ value: Value) {
        // do some something here or in background queue
        DispatchQueue.main.async {
            self.storage.wrappedValue = value
        }
    }

}


struct TestPropertyWrapper: View {

    @Refreshing var counter: Int = 1
    var body: some View {
        VStack {
            Text("Value: \(counter)")
            Divider()
            Button("Increase") {
                self.counter += 1
            }
        }
    }
}

struct TestPropertyWrapper_Previews: PreviewProvider {
    static var previews: some View {
        TestPropertyWrapper()
    }
}

这篇关于期望 SwiftUI DynamicProperty 属性包装器的内部更新触发视图更新是否正确?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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