IBInspectable不能渲染NSView的层

时间:2015-06-16 10:21:34

标签: macos swift interface-builder

我想修改NSView的边框宽度和背景颜色,并将这些值设为IBInspectable

@IBInspectable var borderWidth: CGFloat{
    set{
        layer?.borderWidth = newValue
    }
    get{
        return layer!.borderWidth
    }
}

@IBInspectable var backgroundColor: NSColor{
    set{
        layer?.backgroundColor = newValue.CGColor
    }
    get{
        return NSColor(CGColor: layer!.backgroundColor)!
    }

}

init方法中,我写道:

override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)

    wantsLayer = true
    layer?.setNeedsDisplay()
}

当我运行应用程序时,更改会正确显示,但视图在界面构建器中不会进行实时渲染。我也没有收到任何错误或警告。

2 个答案:

答案 0 :(得分:2)

我自己找到了解决方案:当在“接口”构建器中呈现视图时,似乎不会调用init方法。作为一种解决方案,我必须添加一个全局变量,在需要时创建CALayer()

@IBDesignable class CDPProgressIndicator: NSView {

// creates a CALayer() and sets it to the layer property of the view
var mainLayer: CALayer{
    get{
        if layer == nil{
            layer = CALayer()
        }
        return layer!
    }
}

//referencing to mainLayer ensures, that the CALayer is not nil 
@IBInspectable var borderWidth: CGFloat{
    set{
        mainLayer.borderWidth = newValue
    }
    get{
        return mainLayer.borderWidth
    }
}

@IBInspectable var backgroundColor: NSColor{
    set{
        mainLayer.backgroundColor = newValue.CGColor
    }
    get{
        return NSColor(CGColor: mainLayer.backgroundColor)!
    }

}

现在它最终也会在界面构建器中呈现。

答案 1 :(得分:0)

wantsLayer的设置足以在运行应用程序时创建图层,但是在IB中不起作用。您必须显式设置layer。例如:

@IBDesignable
class CustomView: NSView {

    @IBInspectable var borderWidth: CGFloat {
        set { layer!.borderWidth = newValue }
        get { return layer!.borderWidth }
    }

    @IBInspectable var borderColor: NSColor {
        set { layer!.borderColor = newValue.cgColor }
        get { return NSColor(cgColor: layer!.borderColor!)! }
    }

    @IBInspectable var backgroundColor: NSColor {
        set { layer!.backgroundColor = newValue.cgColor }
        get { return NSColor(cgColor: layer!.backgroundColor!)! }
    }

    override init(frame frameRect: NSRect = .zero) {
        super.init(frame: frameRect)
        configure()
    }

    required init?(coder decoder: NSCoder) {
        super.init(coder: decoder)
        configure()
    }

    private func configure() {
        layer = CALayer()
        // wantsLayer = true
    }
}

我发现这些图层属性就足够了。

恼人的是,子层似乎根本没有在IB中渲染。最重要的是,我得出结论说,macOS中这种基于层的可设计视图的实现已被破坏。在iOS上运行良好,但在macOS上无法运行。