在Swift 5.1的属性包装器中访问self

7

我想创建一个属性包装器,它可以使我的 UICollectionViewLayout 的布局失效。

因此,我创建了这个属性包装器

@propertyWrapper
class LayoutInvalidating {
    private let layout: UICollectionViewLayout

    init(layout: UICollectionViewLayout) {
        self.layout = layout
        self.wrappedValue = layout
    }

    var wrappedValue: UICollectionViewLayout {
        didSet {
            self.layout.invalidateLayout()
        }
    }
}

然后,我想按照以下方式使用它。
final class VehicleControlsCollectionViewLayout: UICollectionViewLayout {
     @LayoutInvalidating(layout: self) // self is not alive
     public var itemSize: CGSize = .init(width: 70, height: 70)
}

每次属性被设置时,我希望调用self.invalidateLayout()。有什么办法可以在self存在时访问它吗?

1个回答

6

很遗憾,目前不可能将self添加到@propertyWrapperinit中-这个属性是在创建self时创建的。

未来将有可能实现-请参考提案引用封闭的“self”在包装器类型中)。


如果你正在寻找某种解决方法,你可以考虑向你的属性包装器添加函数,并在类的init后调用该函数:

@propertyWrapper
class LayoutInvalidating<Value> {
    private var layout: UICollectionViewLayout?

    init(wrappedValue: Value) {
        self.wrappedValue = wrappedValue
    }

    func configure(with layout: UICollectionViewLayout?) {
        self.layout = layout
    }

    var wrappedValue: Value {
        didSet {
            layout?.invalidateLayout()
        }
    }
}

final class VehicleControlsCollectionViewLayout: UICollectionViewLayout {
    @LayoutInvalidating
    public var itemSize: CGSize = .init(width: 70, height: 70)

    override init() {
        super.init()
        _itemSize.configure(with: self)
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接