A more insightful look into IBDesignable and IBInspectable

Intro

If you’re an iOS developer, you’ve probably come across the keywords IBDesignable and IBInspectable at some point. Their concept is fairly simple and easy to grasp: An IBInspectable property can be set from the Interface Builder, and an IBDesignable view will reflect your IBInspectable property changes immediately in the IB after your set it. However, most guides only talk about the basic usage, accompanied by a few lines of code. This is completely sufficient for people who like to experiment and find out more by themselves. In this article -in addition to the usage- I’d like to go into a little bit more detail, to help you avoid some pitfalls, while dishing out a few useful tips as well.

Basic usage on iOS

The gist is simple: Add the IBDesignable annotation to your view class, and add your desired properties with their IBInspectable annotations. Set these properties in the IB, see the fruit of your labour in front of your eyes.  Easy.

Here’s a short example code:

The properties can be accessed from the Attributes Inspector of your view, once you’ve set your custom class in the Identity Inspector:

ios custom class attributes inspector

 

 

 

 

ios custom class

Go ahead and set the cornerRadius to 40! Lo and behold, our view changed its appearance in the designer view.

ios set radius to

If you add new inspectable properties while the custom view is already present in your XIB/Storyboard, sometimes you need to manually refresh your views from the Editor menu. Speaking of view refreshing, you should consider turning off the automatic refresh option when you’re not making changes to your IBDesignable classes. If it’s turned on, the project will continously try to refresh all designable elements, sometimes eating up a considerable amount of your computer’s resources.

ios refresh designable elements

As you can see, our properties are listed in the Identity Inspector as User-defined runtime attributes:

ios properties identity inspector

This is because iOS uses Key-Value-Coding to set the IBInspectable properties at runtime, so make sure not to alter the keys listed here. Now let’s remove cornerRadius from the class! Can you spot the error on the following screenshot that was taken after deleting it?

ios - IBInspectable remove cornerradius

 

 

 

Exactly. Xcode doesn’t automatically remove the key-values when we remove a property, so make sure to delete it, otherwise you’ll get runtime warnings about the good old key-value compliancy. These can be hard to find-and-fix when you have a significant amount of interface files. At least these don’t crash the app.

In the end, this is the monstrosity that I “designed” (I’m using this term very generously), using the IB alone. I think I chose well not to become a design artist (smile)

ios design

The not-so-good parts

So far everything is fine and dandy. Unfortunately, at this point in time, there are some problems/shortcomings when it comes to IBDesignable views. Hopefully we’ll get some improvements in the future.

You’ve probably noticed that the IB can’t fill the default values for the custom properties. Sadly, there’s nothing we can do about it, we’ll have to wait for Apple to fix it.

My main disappointment is the lack of interconnection between properties while designing. If you look at a UISlider and start changing the current value in the editor, the Min/Max values will be adjusted accordingly. Turns out that this feature is in the base implementation of Xcode, and it differs from the way IBDesignable works (in the background, I mean).

I made a “round into a circle” boolean property so I can easily achieve said effect:

Sadly, if I manually change the cornerRadius to a different value, the circle switch stays “On”. Ideally, these options should be mutually exclusive, disabling each other, and they ARE, but only codewise during runtime. These exclusivities are not reflected in the IB, which leads to confusion and chaos, and ultimately, the dark side.

ios vader - IBDesignable and IBInspectable Skip to end of metadata

I’ve also noticed that in case of bigger projects that are borderline monolithic, sometimes the designables fail to load altogether.

Conclusion

Is this a good feature? Certainly. Is it perfect? Not by a long shot. But as long as your project’s size is manageable, it’s definitely a good idea to create a designable base class for your views/buttons/etc. It’s really cool and satisfying to see your changes on the drawing board instantly, and a well-written base class can help save you a lot of coding in the future.

Let’s hope that the minor flaws will be corrected in the near future, personally I’m looking forward to it.

Until then, follow Team Wanari on FB or on Twitter for more articles and have fun using this neat little tool!

 

Tamás Keller

Tamás Keller

I like my coffee how I like my code. Without bugs in it.