Using iOS 4’s IBOutletCollection

by Bob McCune on January 31, 2011

Cocoa has long defined the IBAction and IBOutlet keywords. These keywords provide metadata hints to Interface Builder providing it some understanding of your underlying code so you can graphically wire instance variables and properties and set target-action behaviors. For instance, whenever you need a pointer to NIB-defined object you would create a property defined as:

The inclusion of the IBOutlet keyword in the saveButton’s property definition makes it visible to Interface Builder allowing this connection to be wired graphically as show below:

Interface Builder

Using IBOutlet makes it very easy to define your UI in Interface Builder and simply “wire” the object references to your code. However, it does come with one major drawback in that the relationship from a NIB-defined object to property/ivar is always 1-to-1; there was no way to define a collection of components as a single property in your code. Thankfully, Apple quietly introduced a new keyword in iOS4+ called IBOutletCollection allowing you to do just this. Let’s take a closer look at an example where this can be useful.

IBOutletCollection

Like the other keywords previously mentioned, you’ll find the IBOutletCollection keyword in UINibDeclarations.h, which is part of the UIKit framework. The new keyword is defined as follows:

You’ll notice that IBOutletCollection takes a class name parameter. This allows you specify what are considered valid values for the collection such as UIView or UIButton. If you’d prefer you can change the “type” argument to id to allow for a heterogeneous collection. So how could this be useful?

Putting IBOutletCollection To Work

I’ve often found times where I needed references to certain components, but really only in an aggregate way so I could change state on them as a group. To do this I’d first need to define separate ivar/property combinations for each component, wire them up in Interface Builder, and then manually collect each pointer into an NSArray and store the collection for later use. Although this works, it is rather tedious and does add unnecessary bloat to your code. A better way to handle this type of scenario is to make use of the IBOutletCollection keyword and wire up this relationship in IB.

In the example below I’ve defined two unique ivars/properties to hold references to my on & off buttons and then an NSArray to hold a collection of other buttons. The on/off buttons are used to change the enabled state of the group of “otherButtons”.

I can now easily wire this together in Interface Builder without the need to write any code to collect and store the references to my group of buttons. This is clearly a contrived example, but I hope you can see the benefit of this small addition to iOS 4.