6

我想创建一个属性包装器,它使我的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 存在时访问它吗?

4

1 回答 1

6

不幸的是,无法添加self@propertyWrappers init- 此属性是在创建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)
    }
}
于 2019-09-24T13:06:35.417 回答