Оболочки свойств: "Невозможно использовать член экземпляра в инициализаторе свойства; инициализаторы свойств запускаются до того, как 'self' станет доступным"

Я пытаюсь создать оболочку свойств ниже

@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

Есть ли способ пропустить эту ошибку?

1 ответ

Вы не можете использовать self а также imageViewHeightConstraint для инициализации этого свойства, поскольку в данный момент его не существует.

Самым простым решением было бы передать ограничение и представление обертке в представлении 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
    }
}

В качестве альтернативы вы можете использовать KeyPath для imageViewHeightConstraint и пройти 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
    }
}
Другие вопросы по тегам