IBDesignable and IBInspectable



Last time we looked at two of the features of the Interface Builder: the Auto Layout and the Stack Views. Today we will look at one last trick, the @IBDesignable and @IBInspectable attributes. Let’s start by creating a new project in Xcode. We would like to have a custom view that consists of an image and some sort of subtitle for it. We are interested in seeing how they look at design time, before we even build and run the project. But stay with me here, you’re so close to finding out how to do that!

Let’s create a new class and name it CustomView.swift. Inside, let’s create a UIImageView and a UILabel and then add them to our view:

class CustomView : UIView {
    
    var label: UILabel!
    var imageView: UIImageView!
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        addSubviews()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        addSubviews()
    }
    
    func addSubviews() {
        imageView = UIImageView()
        addSubview(imageView)
        label = UILabel()
        addSubview(label)
    }
}

Let’s also add the layoutSubviews() method to configure the image and label properties:

override func layoutSubviews() {
    super.layoutSubviews()
    layer.borderWidth = 0.5
    layer.cornerRadius = 5
    imageView.frame = self.bounds
    imageView.contentMode = UIViewContentMode.ScaleAspectFit
    label.frame = CGRectMake(0, bounds.size.height - 40, bounds.size.width, 40)
    label.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.1)
    label.textAlignment = .Center
    label.textColor = .grayColor()
}

In the storyboard let’s add a UIView and in Identity Inspector change its class to CustomView, and finally set constraints for it, like this:

alt text

The imageview and label are displayed now, but they are both empty! Here comes the magic. Modify the class signature to include the @IBDesignable attribute and add the following method:

@IBDesignable class CustomView : UIView {
    
    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        label.text = " iPhone 6s Plus"
        let url = "http://i.telegraph.co.uk/multimedia/archive/03058/iphone_6_3058505b.jpg"
        imageView.image = UIImage(data: NSData(contentsOfURL: NSURL(string: url)!)!)
    }
...

Now go to the storyboard and, voila! There is an image and text underneath. And all this was accomplished by using the IBDesignable attribute. There is a catch about the prepareForInterfaceBuilder() method though. Although it’s compiled for runtime, code called from prepareForInterfaceBuilder never gets called except by the Interface Builder at design time, so if you run the app nothing will displayed this time. Go ahead and see for yourself. So let’s comment out that method:

//    override func prepareForInterfaceBuilder() {

//        super.prepareForInterfaceBuilder()

//        label.text = " iPhone 6s Plus"

//        let url = "http://i.telegraph.co.uk/multimedia/archive/03058/iphone_6_3058505b.jpg"

//        imageView.image = UIImage(data: NSData(contentsOfURL: NSURL(string: url)!)!)

//    }

Next, let’s make use of the other attribute we mentioned in the beginning, @IBInspectable. So let’s add this last piece of code we need:

@IBInspectable var text: String? {
    didSet { label.text = text }
}

@IBInspectable var image: UIImage? {
    didSet { imageView.image = image }
}

This allows us to set values for variables in Attributes Inspector so if you go there now, you will notice a new section appears for our UIView, named CustomView, under Attributes Inspector, and it has two fields: Text and Image. If you want, you could download that iPhone image from the URL we used above (or any other image you want) and add it to the project. Next, if you click the Image drop down menu, you should be able to choose it, and it will be displayed in real time, like this:

alt text

Lastly, write iPhone 6s Plus (or anything else you want) and it will show on the label on top of the image, in real time as well:

alt text

These are two powerful attributes that are very useful when designing your apps, without having to actually build and run your app. There are unlimited opportunities for using these attributes. Imagine playing with numbers that show a completion wheel spinning in real time, or colors that change as you are watching them live.

Until next time!