您可以使用类别/扩展名向UIView添加IBDesignable属性吗?

Dun*_*n C 17 interface-builder ios xcode-storyboard ibdesignable ibinspectable

对于那些不知道我在说什么的人,Xcode 6.0增加了新功能,IBDesignable和IBInspectable.

使用IBInspectable属性标记自定义视图时,这些属性将显示在IB中的"属性"检查器中.

同样,当您使用IBDesignable标记自定义UIView子类时,Xcode会编译您的视图并调用代码以在Xcode窗口中直接呈现视图对象,以便您可以看到它们的外观.

在自定义视图中添加IBDesignable和IBInspectable属性的技术在Swift和Objective-C中非常相似.IBInspectable属性显示在Interface Builder Attributes Inspector中,无论您使用哪种语言来定义它们.

我在Objective-C中创建了一个UIView类,并在Swift中创建了UIView的扩展,它将视图底层的borderWidth,cornerRadius,borderColor和layerBackgroundColor属性提升为视图的属性.如果更改属性,则扩展名/类别会根据需要键入转换,并将更改转发给图层.

IBInspectable部分运作良好.我看到并可以在IB属性检查器中设置新属性.

我可以在上周发誓,我的视图类别/扩展名上的IBDesignable属性也正常工作,我可以在IB中看到我的自定义UIView类别渲染,它具有更改的图层属性.本周它没有用.

我是产生幻觉的吗?

现有系统类的类别/扩展可以在使用IBDesignable设置时在Interface Builder中绘制自定义UI吗?

Dun*_*n C 25

自发布此问题以来,我了解到@IBDesignable不适用于类扩展.您可以添加标记,但它没有任何效果.


Pau*_*kis 7

我能够使用下面的代码使其工作,但副作用是有时故事板中的 IB 代理会崩溃,因为它必须刷新太多 UI 元素。重新启动 Xcode 会暂时修复问题,直到下次崩溃。也许这就是 OP 面临的问题

@IBDesignable
extension UIView
{

    @IBInspectable
    public var cornerRadius: CGFloat
    {
        set (radius) {
            self.layer.cornerRadius = radius
            self.layer.masksToBounds = radius > 0
        }

        get {
            return self.layer.cornerRadius
        }
    }

    @IBInspectable
    public var borderWidth: CGFloat
    {
        set (borderWidth) {
            self.layer.borderWidth = borderWidth
        }

        get {
            return self.layer.borderWidth
        }
    }

    @IBInspectable
    public var borderColor:UIColor?
    {
        set (color) {
            self.layer.borderColor = color?.cgColor
        }

        get {
            if let color = self.layer.borderColor
            {
                return UIColor(cgColor: color)
            } else {
                return nil
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这就是为什么我试图添加where子句以减少应该扩展此功能的子类: Generic IBDesginables UIView extension