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에서 테스트).
코드는 다음과 같습니다.
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()
}
}