IB_DESIGNABLE Custom Views in Interface Builder

Xcode 6 added two really useful features that make it possible to view and modify custom views live in Interface Builder.

You can waste a lot of time when developing a custom view tweaking the appearance and then building and running to see the results. I have a very simple custom view for showing a power level as a horizontal coloured bar. The screenshot below shows how it looks by default when the level is at 50%:

When the level falls below a threshold (30% by default) the bar colour changes to red:

The implementation of the view is not important for the purposes of this post. The comments in the class interface file (LevelView.h) should give you the basic idea of how it is intended to work:

@interface LevelView : UIView
/**
 The current level value in the range 0.0 - 1.0. Defaults to 1.0.
 */
@property (nonatomic, assign) CGFloat value;
/**
 The threshold value in the range 0.0 - 1.0 at which the bar color
 changes between emptyColor and fullColor. Default is 0.3.
 */
@property (nonatomic, assign) CGFloat threshold;
/**
 The border width for the frame surrounding the bar. Default is 2.0.
 */
@property (nonatomic, assign) CGFloat borderWidth;
/**
 The color of the bar border. Default is black.
 */
@property (nonatomic, copy)   UIColor *borderColor;
/**
 The color of the bar when value >= threshold. Default is green.
 */
@property (nonatomic, copy)   UIColor *fullColor;
/**
 The color of the bar when value < threshold. Default is red.
 */
@property (nonatomic, copy)   UIColor *emptyColor;
@end

To test out the custom LevelView I added it to a view with a UIStepper that allows me to change the power level:

- (IBAction)changeValue:(UIStepper *)sender {
  self.levelView.value = sender.value;
}

The problem is that custom views like this are pretty much invisible to Interface Builder. This is how the Storyboard scene for my view controller looks by default:

My custom view is not even really visible unless I select it which makes layout a pain and I have to run the app in the Simulator to have any idea how the view appears.

Designable Views

Xcode 6 introduced the ability to have live custom views in Interface Builder and it turns out to be trivial to enable. Add the keyword IB_DESIGNABLE (@IBDESIGNABLE if you are using Swift) before the interface definition in the class header file:

IB_DESIGNABLE
@interface LevelView : UIView

The custom view in our Storyboard now magically comes to life:

Note: WWDC 2014 session 411 What’s New in Interface Builder mentions that you need create a framework for your custom view class - that is no longer required.

Inspectable Properties

The view is live in Interface Builder but our application code is not running so I cannot click on the UIStepper and modify the value to see how it reacts. To allow us to modify the view properties directly in Interface Builder we need to make them Inspectable. This is also trivial we just add the keyword IBInspectable to each of the properties we want to access in Interface Builder:

@property (nonatomic, assign) IBInspectable CGFloat value;

Now with the custom view selected the Attributes inspector has all our custom properties. Even better we can modify the properties and the live view updates. It is even smart enough to understand which properties are of type UIColor and show us the color picker.

I can play around with the value, color, border width and border color in Interface Builder without having to build and run:

If you check the Identity Inspector you will notice that the inspectable properties show up as user defined runtime properties. Deleting any of these properties gets you back to the default.

Get the Code

The full sample Xcode project, with both Objective-C and Swift versions, is available in my GitHub repository.