I'm having a problem and I couldn't find anyone else on the web with the same struggle, maybe it's just too silly.
I have the following class:
class UIXOColourPicker : UIView {
@IBInspectable var moodValue: Int!
...
}
And in my storyboard I have a view just like this:
The user defined runtime attribute was generated by Xcode IBInspectable functionality (which is really cool btw), but whenever I try to run the app I get the error
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UIXOColourPicker 0x7fa86877c420> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key moodValue.'
I'm on Xcode 6 - Beta 6.
Any ideas?
Sorry if it's a silly question, but I've been struggling with it for like 2 hours and I don't have any other Swift developer here to have a look at it.
Cheers
@IBInspectable
uses cocoa objects and not native swift types. So, anything that isn't implicitly convertible to a swift type needs to be a cocoa object instead. For Number
or Bool
you'd need NSNumber
. For something like Point
, Size
, Rect
, etc, you'd need to use NSValue
. However, for String
you can use String
directly; you don't need to use NSString
.
So, in your case, you need to use NSNumber
instead of Int
. I'd also use NSNumber?
instead of NSNumber!
in case the value isn't set in your storyboard/xib.
@IBInspectable var moodValue: NSNumber?
As @JakeLin and @Echelon pointed out, for int
like values, Xcode will only show the attribute in the Attributes Inspector if you declare it as an Int?
, but then it will crash at runtime. If you use an NSNumber?
, it won't crash at runtime, but the attribute won't be available in the Attributes Inspector anymore; it will only show up in the User Defined Runtime Attributes (this seems like a bug in Xcode to me).
The error itself tells us how to get around that problem though:
IBInspectable[66994:58722469] Failed to set (moodValue) user defined inspected property on (q25429792___IBInspectable.ViewController): [ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key moodValue.
What this is saying is that the runtime can't find a "key value coding-compliant" attribute on the class for moodValue
(Int
attributes aren't key value coding-compliant) and that you can implement setValue:forUndefinedKey:
to fix that.
In that case, the implementation might look something like this:
@IBInspectable var moodValue: Int?
override func setValue(value: AnyObject?, forUndefinedKey key: String) {
if let value = value as? Int? where key == "moodValue" {
self.moodValue = value
}
}
So, if you really want the attribute to show up in the Attributes Inspector and you don't mind adding the extra method, declare your property as an Int?
and implement setValue:forUndefinedKey:
. If you don't want the extra method, you'll have to content yourself with using an NSNumber?
and the User Defined Runtime Attributes UI.
This is down to your type for moodValue
. It seems the KVO system can't handle the type coercion needed; it's looking for a moodValue
with the actual type NSNumber
. Changing
@IBInspectable var moodValue: Int!
to
@IBInspectable var moodValue: NSNumber!
Then picking out the moodValue.integerValue
should do what you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With