IB Hack - Setting the runtime variables

23 Jul 2012

This post is about reducing your controller lines of code, and moving some stuff in the Interface Builder.
If you already know why this is for
and why setting this attributes can't be read in code you can skip this post.
<!-- more -->

Intro

Let's say you have a form with 20 text fields, and various other inputs.
When the text field looses focus, you want to save it's value to the database.
When you open that screen later again, you want all the values preloaded.

-(void)textFieldDidEndEditing:(UITextField*)textField{if(textField==nameField)//store the name in the database, e.g.self.form.name=textField.text;elseif(textField==surnameField)self.form.surname=textField.text;elseif(textField==middleNameField)self.form.middleName=textField.text;// and so on}-(void)viewDidLoad{[superviewDidLoad];self.nameField.text=self.form.name;self.surnameField.text=self.form.surname;self.middleNameField.text=self.form.middleName;// and going...}

Logically, if you had 20 of this inputs, your controller would get bloated. A lot.
The second problem is, if you change the database field, you need to change the controller (and probably the view).
That's violating the SRP principle.

Motivation

Wouldn't it be great if you could give those fields the same identifier as the database fields are called?
For instance, if a Person has name , surname ,... then your fields identifiers should be name , surname ,...
If you can manage that, than the above methods could become very short.

123456789

-(void)textFieldDidEndEditing:(UITextField*)textField{[self.formsetValue:textField.textforKey:textField.myAwesomeIdentifier];}-(void)viewDidLoad{[superviewDidLoad];for(idinputinself.view.subviews)// this is more a pseudo. Your view can be differently structured.input.text=[self.formvalueForKey:input.myAwesomeIdentifier];}

Y U NO Interface Builder?

Let's say we want to make a small hack, and use the Accessibility (label, hint, identifier) for myAwesomeIdentifier.
You can set these values in the IB,
but you can't read them in the code.

I'm not advocating the usage of accessibility-stuff.
You should probably subclass the UI*Component and that way document your code better, open some new possibilities, etc.
Let's say I've made a FormTextField, with 2 properties: required , and databaseField.
In that case the IB would look like: