Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using IBDesignable and prepareForInterfaceBuilder with a UILabel

I have a subclass of UIView called MyView that I am creating.

In it there is a UILabel (this is added in code not in InterfaceBuilder for reasons).

I then have a property on MyView called color.

What I'd like is to have Interface Builder be able to select the color and also to then display the label with the font set to that color.

In my code I have...

@IBDesignable class MyView: UIView {

    private let textLabel = UILabel()

    @IBInspectable var color: UIColor = .blackColor() {
        didSet {
            textLabel.textColor = color
        }
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        initialSetup()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)

       initialSetup()
    }

    private func initialSetup() -> Void {
        self.backgroundColor = .clearColor()

        textLabel.textAlignment = .Center
        textLabel.numberOfLines = 0

        addSubview(textLabel)
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        textLabel.frame = bounds
    }

    // I have no idea what I'm doing here?!
    override func prepareForInterfaceBuilder() {
        // should I create a label specifically for here?
        // or should I use the property textLabel?

        textLabel.text = "Hello, world!" // setting place holder IB text?
        textLabel.textColor = color
        textLabel.font = .systemFontOfSize(21)
        textLabel.textAlignment = .Center
        textLabel.numberOfLines = 0

        // do I need to add sub view?
    }

}

IBInspectable

In IB I can see the color property there and I can set it. Annoyingly it takes a default value of .clearColor() though not the color I set in code. Is there a way to fix that?

IBDesignable

When I put the view into InterfaceBuilder it shows all the inspectable properties but nothing is shown in the actual view.

When I run it it all works fine. I'd just like to be able to get something working (other than drawRect) in IB. I'm finding a distinct lack of documentation though.

Edit - Warnings

I just noticed that I'm getting build errors / warnings saying...

warning: IB Designables: Ignoring user defined runtime attribute for key path "color" on instance of "UIView". Hit an exception when attempting to set its value: [ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key color.

This will probably change the solution :)

like image 709
Fogmeister Avatar asked Jan 22 '15 12:01

Fogmeister


3 Answers

I copied the code from your question into a new app, added the view and set the property and it worked just fine.

The error you're seeing suggests that at some point you've changed the view back to a plain UIView in the identity inspector (the user defined attributes remain in that case).

enter image description here

like image 134
jrturton Avatar answered Nov 17 '22 06:11

jrturton


When color is set you need to update the textLabel property like below using a didSet

@IBInspectable var color: UIColor = UIColor.blackColor() {
    didSet {
        textLabel.textColor = color
    }
}
like image 25
topher91 Avatar answered Nov 17 '22 07:11

topher91


I am using swift 2.0 and in my case was missing dynamic property. Final code:

@IBInspectable dynamic var radius:CGFloat = 2.0 {
    didSet {
     //   setNeedsDisplay()
        layer.cornerRadius = radius

    }
}

Find out error during build for IB Designables: http://lamb-mei.com/537/xcode-ibdesignables-ignoring-user-defined-runtime-attribute-for-key-path-bordercolor-on-instance-of-uiview-this-class-is-not-key-value-coding-compliant-for-the-key-bordercolor/

like image 37
Ramis Avatar answered Nov 17 '22 06:11

Ramis