我正在尝试创建 SwiftUI 支持的自定义属性包装器,这意味着对相应属性值的更改将导致 SwiftUI View 的更新。这是我所拥有的简化版本:
@propertyWrapper
public struct Foo: DynamicProperty {
@ObservedObject var observed: SomeObservedObject
public var wrappedValue: [SomeValue] {
return observed.value
}
}
我看到了,即使我的
ObservedObject
包含在我的自定义属性包装器中,SwiftUI 仍会捕获对 SomeObservedObject
的更改只要:DynamicProperty
不幸的是,文档很少,我很难判断这是否仅适用于当前的 SwiftUI 实现。
DynamicProperty
的文档(在 Xcode 中,而不是在线)似乎表明这样的属性是从外部更改的属性,导致 View 重绘,但是不能保证当您使自己的类型符合该协议(protocol)时会发生什么。我可以期望这在 future 的 SwiftUI 版本中继续工作吗?
最佳答案
您可以使用您的 @propertyWrapper
创建和使用组合发布者。同理一个@Published
来自 SwiftUI 的对象会做。
通过您的 @porpertyWrapper
的发布者到 projectedValue
,您将拥有一个自定义的 Combine 发布者,您可以在 SwiftUI View 中使用它并调用 $
跟踪值随时间的变化。
在 SwiftUI View 或 View 模型中使用:
@Foo(defaultValue: "foo") var value: String
// For your view model or SwiftUI View
$value
您的完整自定义组合发布者为 @propertyWrapper
:import Combine
@propertyWrapper
struct Foo<Value> {
var defaultValue: Value
// Combine publisher to project value over time.
private let publisher = PassthroughSubject<Value, Never>()
var wrappedValue: Value {
get {
return defaultValue
}
set {
defaultValue = newValue
publisher.send(newValue)
}
}
// Project the updated value using the Combine publisher.
var projectedValue: AnyPublisher<Value, Never> {
publisher.eraseToAnyPublisher()
}
}
关于swift - 期望 SwiftUI DynamicProperty 属性包装器的内部更新来触发 View 更新是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59580065/