无法在 UIView 中设置 @IBInspectable computed 属性

Can't set @IBInspectable computed property in UIView

我正在尝试向 UIView 添加 IBInspectable 颜色,以便我可以在情节提要中设置它,然后在代码中使用它。在 this post regarding UITextField 中,我看到我可以利用扩展并添加一个计算的 属性,但我无法使其适用于 UIView。

我崩溃了:无法设置(additionalColor1)用户定义检查 属性 on (UIView): [setValue:forUndefinedKey:]: 这个 class 是键 additionalColor1 不符合键值编码。

知道是什么原因导致崩溃以及如何修复它吗?

这是我的代码:

extension UIView {
    @IBInspectable var additionalColor1: UIColor? {
        return self.additionalColor1
    }
}

作为参考,我粘贴了可用于为 UITextField 设置占位符颜色的代码(与上述 url 相同)。这工作正常:

extension UITextField {
    @IBInspectable var placeHolderColor: UIColor? {
        get {
            return self.placeHolderColor
        }
        set {
            self.attributedPlaceholder = NSAttributedString(string: self.placeholder != nil ? self.placeholder! : "", attributes:[NSForegroundColorAttributeName: newValue!])
        }
    }
}

如您的问题标题所述

Swift extensions can only add computed properties to a type, but they cannot add stored properties.

(更详细的信息请参考Extension chapter in The Swift Programming Language。)

您 post 编辑的示例实际上存在缺陷 — 即使此时它在 Whosebug 上有 50 个赞成票。如果您 return 来自 属性 的 getter 的 属性 本身的值,那么您正在创建一个循环。

@IBInspectable var additionalColor1: UIColor? {
    return self.additionalColor1
}

如果您有 view 并尝试在代码中的任何位置访问 view.additionalColor1,您的 属性 的 getter 将被调用 return s self.additionalColor1 — 或者换句话说:它 returns 又是 属性 的值 — 猜猜怎么回事?通过调用 属性 的 getter! (等等...)

您提到的 post 中的示例仅 "works" 因为 getter 显然从未被调用过。只有 setting 计算 属性 placeHolderColor 改变另一个存储的 属性,即文本字段的 attributedPlaceholder.

因此,虽然您可以通过扩展将 computed 属性添加到现有 class,但您可以 never 将其视为存储在某处的具体值。计算属性只能用于以某种方式转换您分配给它的值并将结果存储在现有存储的 属性中。

你的 additionalColor 将如何使用?

我最近不得不做类似的事情,但就我而言,我总是立即应用额外的价值。

例如,我想创建一个看起来像平行四边形的按钮。所以,我想要一种在 Storyboard 中输入值的方法,它将应用 CGAffineTransform。我并没有真正存储偏斜值,只是用来改变事物的外观。然后,在 get 中,我从视图的 affineTransform 例程传回值。

@IBInspectable var skewOffset: Float {
    set(newSkewOffset) {
        let affineTransform : CGAffineTransform = CGAffineTransform(a: 1.0, b: 0.0, c: CGFloat(newSkewOffset), d: 1.0, tx: 0.0, ty: 0.0)
        layer.setAffineTransform(affineTransform)
    }
    get {
        return Float(layer.affineTransform().c)
    }
}

所以,我没有存储 skewOffset,我正在应用它,并且我知道如果我需要它,我以后可以如何查找它。