Need help getting IBDesignable working

502 views Asked by At

I cannot get my custom button to live preview basic examples and this is putting me off using what would otherwise be a great help to my development (IBDesignable).

My custom button code is as follows:

import Cocoa
@IBDesignable class MyButton: NSButton {

    @IBInspectable var name:String = "Bob"{
        didSet{
            setup()
        }
    }

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

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

    override func prepareForInterfaceBuilder() {
        setup()
    }

    func setup(){
        self.title = name
        self.setNeedsDisplay()
    }

    override func drawRect(dirtyRect: NSRect) {
        super.drawRect(dirtyRect)
        // Drawing code here.
    }

}

I then drag either a Custom view OR a NSButton onto my canvas (mainmenu.xib) and adjust its class type in the inspector window to MyButton. The inspectable field pops up and there are no errors BUT my custom button does NOT change its name when I change its value in the property panel!

Further, when I drag a custom view onto the canvas all I get is a blank/transparent rectangle in place of a button (after changing the class to MyButton).

Any assistance would be greatly appreciated. This has been driving me nuts!

1

There are 1 answers

0
Rob On

I had to put the button inside a NSView:

@IBDesignable
public class MyButton: NSView {

    @IBInspectable var name: String = "Bob" {
        didSet{
            button?.title = name
        }
    }

    public var touchUpHandler: (() -> Void)?

    private weak var button: NSButton!

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

    required public init?(coder: NSCoder) {
        super.init(coder: coder)
        configureView()
    }

    private func configureView() {
        let button = NSButton(title: name, target: self, action: #selector(didTapButton(_:)))
        button.bezelStyle = .regularSquare
        button.translatesAutoresizingMaskIntoConstraints = false
        addSubview(button)
        NSLayoutConstraint.activate([
            button.topAnchor.constraint(equalTo: topAnchor),
            button.leftAnchor.constraint(equalTo: leftAnchor),
            button.rightAnchor.constraint(equalTo: rightAnchor),
            button.bottomAnchor.constraint(equalTo: bottomAnchor)
        ])
        self.button = button
    }

    func didTapButton(_ sender: NSButton) {
        touchUpHandler?()
    }

}

And then I used it like so:

@IBOutlet weak var myButton: MyButton!

override func viewDidLoad() {
    super.viewDidLoad()

    myButton.touchUpHandler = { [unowned self] in
        self.performSomeAction()
    }
}