Xcode – Using IB to configure custom classes

I didn’t know it could be done until yesterday, the day I learned one of the most useful tricks in Xcode / Interface Builder. I like Interface Builder – it makes it pretty easy to configure things that are otherwise boring and time-consuming to configure in code. That and I’m a visual learner – I always have a pad of paper and a pen whenever I’m working out some ideas.

So I found out yesterday how to do something very useful, and that’s being able to configure the properties of your custom views in Interface Builder! Surely not! Normally I create outlets for all of them and am forced to set their properties in my UIViewController’s viewDidLoad method. Well, not anymore! (providing the properties are pretty basic, i.e. strings, numbers, structs)

Take the following example. I want to make a piano keyboard, and I want a key to know which sound he is responsible for playing. If I were to do things the old way (and also wanting to avoid a lot of glue code in my viewDidLoad), I would do it as below; use the tag property of a view to set a runtime attribute: in this case the keyNum property. (88 keys on a keyboard, right? might as well use ints!)

//
//  TPKey.h
//  DDRToyPiano
//
//  Created by Stephen O'Connor on 10/4/11.
//  Copyright 2011 Stephen O'Connor. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface TPKey : UIView {

}
@property (nonatomic, assign) NSInteger  keyNum;  // wraps the UIView's tag property.
@property (nonatomic, assign) NSUInteger  velocity;

@end

This however is arguably less ‘human readable’ and it would be nicer to use another property, such as a string, that can more easily identify a key. For example, C0, D2, F4, etc. so i know which note it is, and which octave. How can I do this in Interface Builder??

Simple. Look more closely at the class inspector pane of your object (where you set the custom class). Even wonder what some of the fields do that you never use because you’re not sure what they do? Yeah, User Defined Runtime Attributes is the secret here.

customruntimeattribs

We can just set him to a custom, KVC compliant property belonging to the custom class, which can now be refactored to:

//
//  TPKey.h
#import <UIKit/UIKit.h>

@interface TPKey : UIView {

}
@property (nonatomic, strong) NSString  *pianoKeyName;  // no longer have to confuse others with these 'tag to something else' transforms, but now use something semantically useful that's less 'wizardry' than before.
@property (nonatomic, assign) NSUInteger  velocity;

@end

What’s also useful to know is the order in which these get set.  Basically the following methods are called in the following order:

initWithCoder:
setValue: forKey:  // i.e. your KVC properties you set in the NIB in runtime attributes
awakeFromNib

 

Isn’t that great! Think of all the outlets and glue code you won’t have to write in your viewControllers!

Advertisements

One thought on “Xcode – Using IB to configure custom classes

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s