IB Designable and Inspectable

One of the new features introduced by Xcode 6 is the ability to render custom views and controls in the design canvas in real-time. This new functionality allows designers and developers to easily change and test attributes from a custom user interface without having to run the app neither on the simulator nor on a real device.

To accomplish that, Xcode 6 introduces two new attributes, IB_DESIGNABLE and IBInspectable. When used in combination, these attributes allow custom elements to be manipulated and rendered within the Interface Builder.

  • IB_DESIGNABLE tells Xcode that the object supports live preview, and
  • IBInspectable turns a property into an inspectable property.

The example below presents a new label class, MyLabel, which subclasses UILabel, using these new attributes.

1
2
3
4
5
6
7
8
9
10
#import <UIKit/UIKit.h>

IB_DESIGNABLE

@interface MyLabel : UILabel

@property (nonatomic) IBInspectable CGSize inset;
@property (nonatomic) IBInspectable CGFloat cornerRadius;

@end

The first inspectable property — CGSize inset — modifies the label’s intrinsic size (useful when using Auto Layouts) and the latter — CGFloat cornerRadius — draws a round corner around it with the given radius. They can be manipulated from the Attributes Inspector panel on Xcode 1 and are placed on top of all the other properties for that class.

Once the properties are exposed in the header file, Xcode must be told how to render the elements. For elements added to the view, the work is done in the drawRect: method. For redefining the intrinsic size, the easiest solution is to change the intrinsicContentSize getter to return the new size.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#import "MyLabel.h"

@implementation MyLabel

- (CGSize)intrinsicContentSize
{
    CGSize intrinsicSize = [super intrinsicContentSize];

    return CGSizeMake(intrinsicSize.width + self.inset.width,
                      intrinsicSize.height+ self.inset.height);
}

- (void)drawRect:(CGRect)rect
{
    [super drawRect:rect];

    self.clipsToBounds = YES;
    self.layer.cornerRadius = self.cornerRadius;
}

@end

The result is a real-time rendered element

The list of types that can be inspected is not limited to those two. Currently Xcode 6 supports the following types:

  • Bool
  • CGFloat
  • CGPoint
  • CGRect
  • CGSize
  • NSInteger
  • NSString
  • UIColor
  • UIImage

For additional information, Apple covers this topic on the documentation page Creating a Custom View That Renders in Interface Builder.


  1. Note that Xcode understands the type and presents an inspector that matches that type.

Copyright © 2014 - Otavio Cordeiro. Powered by Octopress