Subclass IBDesignable UIButton

I am trying to implement a simple subclass of UIButton, which is IBDesignable. I need the ability to set a color for each control state from Interface Builder. I know this is possible with the IBInspectable keyword. I am having problems with IB failure when using state owned KVOs. The IBDesignable debugger crashes. Does anyone know how I can work with KVO and IBDesignable together?

@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) } } 
+6
source share
2 answers

I had something similar, the problem was the init() method, which caused a crash after refactoring my code, which works like a charm. Perhaps this will help you:

 #if !TARGET_INTERFACE_BUILDER required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) self._setup() } #endif override func prepareForInterfaceBuilder() { self._setup() } 
+6
source

For Xcode 7.2, the general code for @IBDesignable UIButton Subclass as follows:

 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() } } 
+6
source

Source: https://habr.com/ru/post/977338/


All Articles