Failed to set () user defined inspected property on (UIButton)

cmii picture cmii · Mar 26, 2017 · Viewed 22.5k times · Source

In a simple ViewController, I added one UIButton. I would like to use "User Defined Runtime Attributes". For now I added the default Bool attribute.

screen

The button is an @IBOutlet:

@IBOutlet var button:UIButton!

The link in the storyboard is done.

I have nothing else in my app.

I got this error:

2017-03-26 20:31:44.935319+0200 ISAMG[357:47616] Failed to set (keyPath) user defined inspected property on (UIButton): 
[<UIButton 0x15e3a780> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key keyPath.

I don't understand what I'm missing.

EDIT 1

Following the advices @timaktimak, I created a custom UIButton class:

@IBDesignable
class ChoiceButton: UIButton {

    @IBInspectable var keyPath: Bool! {
        didSet {
            print("didSet viewLabel, viewLabel = \(self.keyPath)")
        }
    }

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

screen2

The error is the same:

2017-03-26 22:32:27.389126+0200 ISAMG[429:71565] Failed to set (keyPath) user defined inspected property on (ISAMG.ChoiceButton): 
[<ISAMG.ChoiceButton 0x14e8f040> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key keyPath.

Answer

timaktimak picture timaktimak · Mar 26, 2017

Well, your button doesn't have a property called keyPath to be setting it to something.

User Defined Runtime Attributes are used to simply set a property value in the Interface Builder.

You can use a standard property that every UIButton has, for example backgroundColor:

enter image description here

Or, you can create a custom UIButton subclass, add a property to it, then set the button's class to the created custom subclass and set the property value in the User Defined Runtime Attributes section.

You can check out, for example, this answer, it contains an example of a custom class with User Defined Runtime Attributes: https://stackoverflow.com/a/24433125/3445458

Edit: make sure you are not using optional (or implicitly unwrapped optional) for the type, it doesn't work with User Defined Runtime Attributes (I guess because the Interface Builder doesn't know whether the value can be set to nil, and so show it in the options or not).

So you can't do

var keyPath: Bool!

instead you can only do

var keyPath: Bool = false

or don't use a default value and set it in the constuctor instead. For some reason it works with an optional String (and in the example they use an optional String), but it doesn't with optional Bool. To conclude, don't use or worry about User Defined Runtime Attributes too much, it is clearer to set the default values in code!

Hope this helps! Good luck!