Using IBDesignable and prepareForInterfaceBuilder with a UILabel
Asked Answered
R

3

10

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 :)

Roark answered 22/1, 2015 at 12:4 Comment(0)
W
2

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

Wallywalnut answered 22/1, 2015 at 12:41 Comment(2)
Well, currently I'm getting a "Segmentation Fault: 11" when trying to run so no idea what is going on. That could be the cause of this. Glad to know I got the actual code right though. I did install Xcode 4 (reasons) today so I wonder if that install has messed around with compilers or something?! Thanks though. Will keep my Swift project :DRoark
OMLG! The seg fault was because I used .clearColor() in an attribute instead of UIColor.clearColor() but there were no errors showing in code. Anyway, all is working now :D Thanks!Roark
Q
1

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
    }
}
Quoits answered 22/1, 2015 at 12:16 Comment(1)
I added that. But I just noticed I'm also getting warnings... "Ignoring User Defined runtime attribute for keyPath color..." Added this into the question.Roark
F
1

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/

Fatten answered 13/11, 2015 at 7:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.