Can't Set @Ibinspectable Computed Property in UIview

Can't set @IBInspectable computed property in UIView

As mentioned in your question title

Swift extensions can only add computed properties to a type, but they cannot add stored properties.

(For more detailed information please refer to the Extension chapter in The Swift Programming Language.)

The example you posted is actually flawed — even if it has 50 upvotes on Stackoverflow at this time. If you return the value of a property itself from the property's getter you're creating a loop.

@IBInspectable var additionalColor1: UIColor? {
return self.additionalColor1
}

If you have a view and you try to access view.additionalColor1 anywhere in your code your property's getter will be called which returns self.additionalColor1 — or with other words: it returns the property's value again — and guess how? By calling the propery's getter! (And so on...)

The example from the post you mentioned only "works" because the getter is evidently never called. It's only setting that computed property placeHolderColor that changes another stored property, namely the text field's attributedPlaceholder.

So while you can add computed properties to an existing class through an extension you can never think of it as a concrete value that's stored somewhere. Computed properties may only be used to somehow transform the value you assign to it and store the result in existing stored properties.

Use @IBInspectable with any UIView subclass within storyboards

Move your code to UIView's @IBDesignable extension like below:

@IBDesignable extension UIView {    
@IBInspectable var cornerRadius: CGFloat {
set {
layer.cornerRadius = newValue
layer.masksToBounds = true
}
get {
return self.cornerRadius
}
}
}

Clear unwanted values/types of previously deifned vars in your GEView. Here are values in inspector.

Sample Image

Properties available in inspector of any UIView, included itself.

Properties avaliable in storyboard interface

IBInspectable does not work for Int or UInt

It should work with Int, UInt, or any other numeric type. I've verified this locally with the code below:

@IBDesignable
class TestViewController: UIViewController {
...

@IBInspectable var test: UInt = 0

...
}

This is showing up and working in interface builder as expected. I would make sure you have @IBDesignable on your class definition and also try doing a clean and deleting derived data.

Value of @IBInspectable set in storyboard not propagated to the code

The correct form would be (note the setter assignment):

@IBInspectable var isAPasswordField: Bool {
get {
return self.isPassword
}

set {
self.isPassword = newValue
}
}

since the actual value have not been (and will not be - at least 'directly') set on isAPasswordField (remember, we are implementing the setter of a computed property after all...)

Also, why don't you just use isPassword directly by marking it as inspectable, avoiding the need for an extra ivar?


PS: newValue is the default name for the to-be-set value. You can read more about it under Shorthand Setter Declaration section in the Swift Programming Language book

Apply IBInspectable to all view types in iOS

You should use an extension instead of a subclass, and access the layer property directly:

extension UIView
{
@IBInspectable var cornerRadius: CGFloat {
get {
return layer.cornerRadius;
}
set(value) {
layer.cornerRadius = value;
}
}

var rounded: Bool {
return layer.cornerRadius > 0.0;
}
}

Note: Since you're not implementing drawRect using @IBDesignable is needless. You can't implement roundedas a settable property this way, but you can have a read-only property for that.



Related Topics



Leave a reply



Submit