In Xcode 6 two new interface builder declaration attributes were introduced: IBInspectable
and IBDesignable
. IBInspectable
exposes class properties in the interface builder Attribute Inspector, and IBDesignable
updates
the view in realtime! They are pure magic!
I can’t wait to see what cool stuff you will make.
tl;dr
a short tutorial on how to use IBInspectable
and IBDesignable
with a video demo. It should take
you around 10 minutes to go through all the steps.
code on github
IBInspectable
These are the valid types for IBInspectable
I found so far:
Int
CGFloat
Double
String
Bool
CGPoint
CGSize
CGRect
UIColor
UIImage
Example:
class OverCustomizableView : UIView {
@IBInspectable var integer: Int = 0
@IBInspectable var float: CGFloat = 0
@IBInspectable var double: Double = 0
@IBInspectable var point: CGPoint = CGPointZero
@IBInspectable var size: CGSize = CGSizeZero
@IBInspectable var customFrame: CGRect = CGRectZero
@IBInspectable var color: UIColor = UIColor.clearColor()
@IBInspectable var string: String = "We ❤ Swift"
@IBInspectable var bool: Bool = false
}
In the Attribute Inspector you will see this on top:
All this does is add some user defined runtime attributes that will set the initial values of the view when it loads.
The runtime attributes created:
IBDesignable
Now for the fun part. IBDesignable
tells Interface Builder that it can load the view and render it. The view class must be in a framework for this to work. But that is not a big inconvenience, as we will
soon see. I think that under the hood Interface Builder converts your UIView code into NSView code so that it could dynamically load the framework and render the component.
Create a new project
Open Xcode 6, create a new “Single Page Application” and select Swift as the programming language.
Add a new target to you project
Select your project file from the navigator and add a new target by pressing the +
button.
Select Framework & Application Library
and choose the Cocoa Touch Framework
.
Name it MyCustomView
. Xcode will automatically link the MyCustomView.framework
to your project.
Create a custom view class
Create a new swift file and add it in MyCustomView
framework.
Right click on the framework’s directory.
Select Cocoa Touch File
Name it CustomView
and make it a subclass of UIView
CustomView.swift
should contain:
import UIKit
class CustomView: UIView {
init(frame: CGRect) {
super.init(frame: frame)
// Initialization code
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func drawRect(rect: CGRect)
{
// Drawing code
}
*/
}
Remove the generated methods.
import UIKit
class CustomView: UIView {
}
Tell Xcode to render your view with the @IBDesignable
keyword.
Add three properties: borderColor: UIColor
, borderWidth: CGFloat
, cornerRadius:
CGFloat
.
Set the default values and make them inspectable.
@IBDesignable class CustomView : UIView {
@IBInspectable var borderColor: UIColor = UIColor.clearColor()
@IBInspectable var borderWidth: CGFloat = 0
@IBInspectable var cornerRadius: CGFloat = 0
}
Add logic for the layer properties
Add property
observers for each property and update the layer
accordingly.
class CustomView : UIView {
@IBInspectable var borderColor: UIColor = UIColor.clearColor() {
didSet {
layer.borderColor = borderColor.CGColor
}
}
@IBInspectable var borderWidth: CGFloat = 0 {
didSet {
layer.borderWidth = borderWidth
}
}
@IBInspectable var cornerRadius: CGFloat = 0 {
didSet {
layer.cornerRadius = cornerRadius
}
}
}
Build the framework by pressing ⌘ Cmd
+ B
.
Test the custom view
Open Main.storyboard
and add a view from the component library.
Change the view class to CustomView
using the Identity Inspector.
Arrange the view and add any autolayout constraints that are needed.
Tip: Hold Crtl
+ ⌘ Cmd
then click and drag the mouse cursor from a view to another to add autolayout constraints.
After playing a bit with the cornerRadius
I found out that it creates some interesting patterns when you add big values.
You can get the code on github.
Have fun
A quick demo: