[swift] SwiftUI DynamicProperty 속성 래퍼의 내부 업데이트가 뷰 업데이트를 트리거 할 것으로 예상됩니까?

SwiftUI에서 지원하는 사용자 정의 속성 래퍼를 만들려고하는데 해당 속성 값을 변경하면 SwiftUI보기가 업데이트됩니다. 여기 내가 가진 것의 단순화 된 버전이 있습니다.

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

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

나는이 경우에도 볼 ObservedObject내 사용자 정의 속성 래퍼의 내부를 포함, SwiftUI 여전히에 대한 변경 잡는다 SomeObservedObject긴만큼을 :

  • 내 속성 래퍼는 구조체입니다
  • 내 속성 래퍼는 DynamicProperty

불행히도 문서는 드물고 현재 SwiftUI 구현에서는 운이 좋지 않은지 말하기가 어렵습니다.

DynamicProperty(온라인이 아닌 Xcode 내) 문서는 이러한 속성이 외부에서 변경되어 속성이 다시 그려지는 속성임을 나타내지 만 자신의 유형을이 프로토콜에 맞출 때 어떤 일이 발생하는지에 대한 보장은 없습니다.

향후 SwiftUI 릴리스에서 계속 작동 할 것으로 기대할 수 있습니까?



답변

좋아 … 여기 비슷한 것을 얻는 대안이 있습니다 …하지만 구조체가 DynamicProperty감싸서 @State(보기 새로 고침).

간단한 래퍼이지만 다음과 같은 뷰 새로 고침을 사용하여 사용자 정의 계산을 캡슐화 할 수 있습니다.

데모는 다음과 같습니다 (Xcode 11.2 / iOS 13.2에서 테스트).

@State의 래퍼로 DynamicProperty

코드는 다음과 같습니다.

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


답변