Is it correct to expect internal updates of a SwiftUI DynamicProperty property wrapper to trigger a view update?

佐手、 提交于 2020-02-13 09:03:25

问题


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
    }
}

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:

  • My property wrapper is a struct
  • My property wrapper conforms to DynamicProperty

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

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.

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


回答1:


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.

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

Here is code:

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()
    }
}


来源:https://stackoverflow.com/questions/59580065/is-it-correct-to-expect-internal-updates-of-a-swiftui-dynamicproperty-property-w

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!