Auto Layout in iOS 6: Adding constraints through code

iOS 6 brings a new feature to design your user interface: Auto Layout. With Auto-Layout it is easier to design the UI for multiple screen sizes and also for multiple languages. You can can use Auto Layout within Interface Builder, altough you must be very careful not to mess up your constraints by accidently moving a UI component on the view. So for this tutorial, we are defining our constraints through code.

Open Xcode and create a new Single View Application. For product name, use ConstraintsCodeDemo and then fill out the Organization Name, Company Identifier and Class Prefix fields with your customary values. Make sure only iPhone is selected in Devices, and that the Use Storyboards is deselected and Use Automatic Reference Counting checkbox is selected.

We will create a simple button, which we want to place in the top left corner of the view. In viewController.m create the follwoing instance variable

@implementation ViewController 
{
UIButton *firstButton;
}

In viewDidLoad create the button and add it to the view

- (void)viewDidLoad 
{
[super viewDidLoad];

firstButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[firstButton setTitle:@"First" forState:UIControlStateNormal];
[firstButton sizeToFit];
firstButton.translatesAutoresizingMaskIntoConstraints = NO;

[self.view addSubview:firstButton];
}

The translatesAutoresizingMaskIntoConstraints property is set to NO to disable the "old" springs and struts method. This property exists for backwards-compability. We will add a leading constraint so the button will shift 20 points inside the view. Add the following code to the bottom of viewDidLoad.

NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:firstButton attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0f constant:20.f];

[self.view addConstraint:constraint];

Auto Layout uses a formula for the relationship between the views:

A = B * m + c

or

viewA-attribute = viewB-attribute * multiplier + constant

In this example the formula will be:

firstButton.NSLayoutAttributeLeading = self.view.NSLayoutAtrributeLeading * 1.0f + 20f

the position of the button left edge is equal of the superview's left edge plus 20.

Add the following constraint to viewDidLoad

constraint = [NSLayoutConstraint constraintWithItem:firstButton attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0f constant:30.f];

[self.view addConstraint:constraint];

This constraint will display the button 30 point from the top edge of the superview. Build and Run. The button is displayed 20 points from the left and 30 points from the top

Press cmd + <- to change the display to landscape view.

Create a new instance variable in the interface section

UIButton *secondButton;

in ViewDidload add the follwoing section to add the second button to the view

secondButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[secondButton setTitle:@"Second" forState:UIControlStateNormal];
[secondButton sizeToFit];
secondButton.translatesAutoresizingMaskIntoConstraints = NO;

[self.view addSubview:secondButton];

This button will be centered to the X-axis of the superview and displayed 40 points from the bottom. Add the following constraints in viewDidLoad

constraint = [NSLayoutConstraint constraintWithItem:secondButton attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0f constant:-40.f];

[self.view addConstraint:constraint];

constraint = [NSLayoutConstraint constraintWithItem:secondButton attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f];

[self.view addConstraint:constraint];

The second button will have a fixed width of 200 points. Add the following constraint.

constraint = [NSLayoutConstraint constraintWithItem:secondButton attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem: nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:200.0f];

[self.view addConstraint:constraint];

Note this constraint only has a relationship to itself and not the superview as this is a fixed size. Because of this the toItem is nil and the attribute parameter is NSLayoutAttributeNotAnAttribute. Build and Run. The fixed button is centered on the X-axis and dipslayed 40 point from the bottom of the superview.

Press cmd + <- to change the display to landscape view.

This was an introduction to using constraints in code, there is much more under the hood but the purpose of this tutorial was to keep things simple, expect more complex examples in a future tutorial.

You can download the source code of the ConstraintsCodeDemo at the ioscreator repository on github.