IBDesignable and IBInspectable with CoreGraphics

Wearable
Working with CoreGraphics can be a developer's nightmare. It’s our bogey-man hiding under the bed.

IBDesignable and IBInspectable

The tedium of constantly rebuilding the app to see your changes has been a long held frustration for many. Now, imagine that you can draw CoreGraphics code in Interface Builder without building the app. Could it be so? Will this nightmare end? Yes, yes it will.

Since Xcode 6 launched, the sun has risen on a whole new world. So we dived right in and sent Jose to explore. Here are his findings:

IBWhat now?

Let me explain... These annotations help us to modify and visualize the changes of the view from the interface builder, but crucially without building the app.

Let’s think about some attributes predefined in Xcode: changing the background and the tint colours, the alpha component of the view, etc.

Changing any of these properties is automatically reflected in our xib file on Interface Builder without doing extra work, so you could match IBInspectable as customised attributes like the image alongside.

IBDesignable

This attribute has been available since Xcode 6 and can be used for both Objective-C and Swift. It applies to the class as a prefix, and it lets Interface Builder know that it should render the view directly in the canvas.

That means that you will see how your custom views will appear without building and running your app after each change.

Depending if you program in Objective-C or Swift, you have to change the way you add as in the image to the left.

Every time you open the Interface Builder, Xcode quickly compiles the nib. This uses the initialisers and the drawing methods to update the xib in real time.

IBDesignable and IBInspectable are related to each other, so while the first one applies to the class definition, the second one applies to the properties.

IBInspectable

Once you set the IBInspectable prefix to the class, you can declare some properties with the IBInspectable prefix. These properties will allow you to change the outlet class in real time. Unfortunately, you can’t modify everything, only a few types can be set to IBInspectable. Here is the full list:

  • Int
  • CGFloat
  • Double
  • String
  • Bool
  • CGPoint
  • CGSize
  • CGRect
  • UIColor
  • UIImage

Though it is limited, that list can still help considerably. You only need to prefix the properties with the IBInspectable keyword and this will automatically add the properties in our Attributes Inspector.

As before it depends, of course, if we program in Objective-C or Swift. What Xcode does is to set those IBInspectable properties as User Defined Runtimes Attributes, as you can see in the screenshot of the Identities Inspector.

As you may guess, you'll need to do something else with the IBInspectable properties - you need to let the view know what we want to do with them. If you want to set a background colour with the IBInspectable property, you need to assign it to the backgroundColor property of the view.

The question then follows…

Where to set it?

You can set it in some places: initializers, drawing methods and (if you program with Swift) in the didSet method of the IBInspectable var:

8th.png

Once you've finished setting the assignments, open the Interface Builder and switch to the Identity Inspector.

Then you should see the following:

9th.png

That means that you've have finished the set up and then can easily modify the properties to view the changes.

CoreGraphics & PaintCode

You can use CoreGraphics as well to draw automatically in the Interface Builder. This saves time and storage. Moreover you can easily change the properties by using IBInspectable properties. Look at the following example to see an approach of what you can do. Keep in mind that you're using CoreGraphics, not images. Not bad eh?

10th.gif

Fortunately, PaintCode generates a class with the drawing methods that helps a lot with the drawing as you'll only need to set that method in the drawRect method.

11th.png

You can also use this to draw the CoreGraphics canvas automatically with IBDesignable and IBInspectable, just follow these steps:

  • Firstly, you'll need to find something to get the methods prototypes automatically and set them in an array or similar. Ideally you'd probably like to avoid unwanted methods, like initializeWithColor and SludgeGreen (have a look at the screenshot above). Fortunately, we came across an Objective-C runtime to achieve it and as the drawing class is prefixed by “draw” the unwanted ones are easily avoided.

12th.png

  • Secondly, you only need to set the IBInspectable properties to change the call automatically, and therefore the image. We tried to find the most user-friendly IBInspectable property to show the developer an intuitive way to see what method is going to be called. If you have the following methods in the PaintCode generated class: drawFish, drawApple, drawSword…then you can show to the user in IB a scroll down list with these methods. Unfortunately IBInspectable doesn’t allow you to set an array, or at least some hints to indicate to the user what is it going to be rendered. The best approach is to use an IBInspectable Int property which will allow you to change the images every time you change the number. Admittedly it’s not very user-friendly so we are trying to find a better way! 1 -> drawFish, 2 -> drawApple, 3 -> drawSword…

13th.png

That allows you to see the results in your IB without running the app! You can easily change more properties by using out IBInspectables. In the example above you'll see I’m changing the canvas colour as well. Internally this is a set colour that is being called for every canvas with setFill.

Check out our example project. It was made for Objective-C and you simply need to open the xib file, go to the attributes inspector and have a play around to see the results.

Useful links

http://www.thinkandbuild.it/building-custom-ui-element-with-ibdesignable/

https://www.weheartswift.com/make-awesome-ui-components-ios-8-using-swift-xcode-6/

http://nshipster.com/ibinspectable-ibdesignable/

This article was originally written for Brightec by Jose Martinez


Looking for something else?

Search over 400 blog posts from our team

Want to hear more?

Subscribe to our monthly digest of blogs to stay in the loop and come with us on our journey to make things better!