swift - 期望 SwiftUI DynamicProperty 属性包装器的内部更新来触发 View 更新是否正确?

标签 swift swiftui property-wrapper

我正在尝试创建 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/

    相关文章:

    ios - didSelectItemAtIndexPath 修改 UICollectionView 中的多个单元格

    ios - 在 swift 代码中使用 fscanf() 函数

    ios - 自定义可折叠 View

    swift - 当 self 尚未初始化时,如何使用属性包装器中的现有属性? ( swift 用户界面)

    Swift - 如何从 View 之外的函数访问@Published var?

    objective-c - 在 Apple 的 NSObject 文档中, "receiver"的含义是什么?

    没有文本内容的 SwiftUI 按钮操作

    swift - 如何在SwiftUI中更改actionSheet的文本颜色

    swift - 无法在标有 @Observable 的类上使用属性包装器

    string - Swift - 如何将连字符/减号转换为+号