Xcode IBD可设计UIButton子类

Xcode IBD可设计UIButton子类,xcode,xcode6,ibdesignable,Xcode,Xcode6,Ibdesignable,我试图实现一个简单的UIButton子类,它是可设计的。我希望能够从Interface Builder为控件的每个状态设置颜色。我知道使用IBInspectable关键字可以做到这一点。在状态属性上使用KVO时,我遇到IB崩溃问题。IBDesignable调试器在Denit上崩溃。有人知道我如何与KVO和IBDesignable一起工作吗 @IBDesignable class UIButtonActionButton: UIButton { @IBInspectable var de

我试图实现一个简单的UIButton子类,它是可设计的。我希望能够从Interface Builder为控件的每个状态设置颜色。我知道使用IBInspectable关键字可以做到这一点。在状态属性上使用KVO时,我遇到IB崩溃问题。IBDesignable调试器在Denit上崩溃。有人知道我如何与KVO和IBDesignable一起工作吗

@IBDesignable
class UIButtonActionButton: UIButton {

    @IBInspectable var defaultColour: UIColor = UIColor.blueColor() {
        didSet {
            self.setNeedsDisplay()
        } 
    }

    @IBInspectable var selectedColour: UIColor = UIColor.blueColor()

    @IBInspectable var disabledColour: UIColor = UIColor.grayColor()

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self._setup()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        self._setup()
    }


    private func _setup(){
        self.addObserver(self, forKeyPath: "state", options: NSKeyValueObservingOptions.New, context: nil)
        self.layer.cornerRadius = 5.0
        self.layer.masksToBounds = true
    }

    override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {
        self.setNeedsDisplay()
    }

    override func drawRect(rect: CGRect) {
        super.drawRect(rect)
        let context = UIGraphicsGetCurrentContext()

        if self.highlighted {
            CGContextSetFillColorWithColor(context, selectedColour.CGColor)
            CGContextFillRect(context, self.bounds)
        } else if self.state == UIControlState.Disabled {
            CGContextSetFillColorWithColor(context, disabledColour.CGColor)
            CGContextFillRect(context, self.bounds)
        } else {
            CGContextSetFillColorWithColor(context, defaultColour.CGColor)
            CGContextFillRect(context, self.bounds)
        }
    }

    deinit {
        self.removeObserver(self, forKeyPath: "state", context: nil)
    }

}
@IBDesignable
类UIButtonActionButton:UIButton{
@IBInspectable var defaultcolor:UIColor=UIColor.blueColor(){
迪塞特{
self.setNeedsDisplay()
} 
}
@IBInspectable var selectedColor:UIColor=UIColor.blueColor()
@IBInspectable var disabledColor:UIColor=UIColor.grayColor()
必需的初始化(编码器aDecoder:NSCoder){
super.init(编码者:aDecoder)
self.\u设置()
}
重写初始化(帧:CGRect){
super.init(frame:frame)
self.\u设置()
}
专用功能设置(){
addObserver(self,forKeyPath:“state”,选项:NSKeyValueObservingOptions.New,上下文:nil)
self.layer.cornerRadius=5.0
self.layer.masksToBounds=true
}
重写func observeValueForKeyPath(键路径:字符串,对象对象:AnyObject,更改:[NSObject:AnyObject],上下文:UnsafeMutablePointer){
self.setNeedsDisplay()
}
重写func drawRect(rect:CGRect){
super.drawRect(rect)
let context=UIGraphicsGetCurrentContext()
如果self.highlighted{
CGContextSetFillColorWithColor(上下文,SelectedColor.CGColor)
CGContextFillRect(上下文,self.bounds)
}如果self.state==UIControlState.Disabled,则为else{
CGContextSetFillColorWithColor(上下文,disabledColor.CGColor)
CGContextFillRect(上下文,self.bounds)
}否则{
CGContextSetFillColorWithColor(上下文,defaultColor.CGColor)
CGContextFillRect(上下文,self.bounds)
}
}
脱硝{
self.removeObserver(self,forKeyPath:“状态”,上下文:nil)
}
}

我遇到了类似的问题,问题是
init()
方法在重构我的代码后导致崩溃,它工作得很好。也许它会帮助你:

#if !TARGET_INTERFACE_BUILDER
required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    self._setup()
}
#endif

override func prepareForInterfaceBuilder() {
    self._setup()
}

对于Xcode 7.2而言,
@IBDesignable ui按钮子类的公共代码如下所示:

import UIKit

@IBDesignable class MyButton: UIButton {

    //this init fires usually called, when storyboards UI objects created:
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.setupViews()
    }

    //This method is called during programmatic initialisation
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }


    func setupViews() {
        //your common setup goes here
    }

    //required method to present changes in IB
    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        self.setupViews()
    }
}

谢谢你给我小费,丹尼尔。我尝试了上述方法,现在它抱怨我的IBInspectable属性不符合键值编码。因此,我只能在运行时使用宏来添加/删除观察者。接受这个宏提示的答案。我注意到,如果删除
setupViews()
调用
init(frame:)
,安装程序在IB和应用程序中仍然有效。我们需要从该初始化调用安装程序有什么原因吗?@PaulVanWieren有趣。我记得,它不起作用。在
setupViews()
中设置断点,并检查调用它的人:)@palvanwieren-如果在代码中创建视图,则使用init(frame:)方法。在故事板和NIB中创建的视图使用init(coder:)方法。如果您不打算在代码中创建视图,则不严格要求使用init(frame:)方法,但通常为了完整性而包含它。这为我节省了大量时间和精力请注意,如果您使用任何@IBInspectable,您将仅在运行时在“awakeFromNib”中设置它们,因此您还需要添加以下内容:override funct awakeFromNib(){super.awakeFromNib()setupViews()}。也许您需要从init(带解码器)中删除setupViews()???