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


10

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 릴리스에서 계속 작동 할 것으로 기대할 수 있습니까?


4
이 주제에 대한 기대가 무엇인지 확실하지 않습니다 ... 마지막 질문에 대한 답? 누군가 "예, 확실히, 당신은 기대할 수 있습니다"라고 대답한다면 정말로 믿을 것입니까? ))
Asperi

답변:


6

좋아 ... 여기 비슷한 것을 얻는 대안이 있습니다 ...하지만 구조체가 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()
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.