属性包装:"Cannot use instance member within property initializer; property initializers run before 'sel



我正在尝试创建以下属性包装

@propertyWrapper
public struct ConstraintValue {
    private let view:UIView
    private let contraint:NSLayoutConstraint
    public init(contraint:NSLayoutConstraint,view:UIView) {
        self.contraint = contraint
        self.view = view
    }
    public var wrappedValue: CGFloat {
        set {
            contraint.constant = newValue
            view.layoutIfNeeded()
        }
        get {
            return contraint.constant
        }
    }
}

但当我尝试使用它时,我会得到"不能在属性初始化器中使用实例成员;属性初始化器在"self"可用之前运行">

@IBOutlet weak private var imageViewHeightConstraint: NSLayoutConstraint!
 @ConstraintValue(contraint: imageViewHeightConstraint, view: self)
 public var imageHeight:CGFloat

有没有办法克服这个错误?

您不能使用selfimageViewHeightConstraint来初始化此属性,因为它目前不存在。

最简单的解决方案是在视图的init()方法中将约束和视图传递给包装器,如下所示:

@propertyWrapper
public struct ConstraintValue {
    var view: UIView!
    var constraint: NSLayoutConstraint!
    public var wrappedValue: CGFloat {
        set {
            constraint.constant = newValue
            view.layoutIfNeeded()
        }
        get {
            return constraint.constant
        }
    }
}
class OurView: UIView {
    var imageViewHeightConstraint: NSLayoutConstraint!
    @ConstraintValue public var imageHeight:CGFloat
    init() {
        super.init(size: .zero)
        _imageHeight.view = self
        _imageHeight.constraint = imageViewHeightConstraint
    }
}

或者,您可以对imageViewHeightConstraint使用KeyPath,并将self传递给视图的init()中的属性包装器。类似这样的东西:

protocol DynamicImageView: UIView {
    var imageViewHeightConstraint: NSLayoutConstraint! { get set }
}
@propertyWrapper
public struct ConstraintValue {
    var view: DynamicImageView?
    private let constraintKeyPath: WritableKeyPath<DynamicImageView, NSLayoutConstraint>
    init(constraintKeyPath: WritableKeyPath<DynamicImageView, NSLayoutConstraint>) {
        self.constraintKeyPath = constraintKeyPath
    }
    public var wrappedValue: CGFloat {
        set {
            view?[keyPath: constraintKeyPath].constant = newValue
            view?.layoutIfNeeded()
        }
        get {
            view?[keyPath: constraintKeyPath].constant ?? 0.0
        }
    }
}
class OurView: UIView, DynamicImageView{
    var imageViewHeightConstraint: NSLayoutConstraint!
    @ConstraintValue(constraintKeyPath: .imageViewHeightConstraint)
    public var imageHeight:CGFloat
    init() {
        super.init(frame: .zero)
        _imageHeight.view = self
    }
}

相关内容

最新更新