In this post I will use the NSLayoutConstraint class to add a label to an UIViewController on a IOS app.
Setting things up
For this demonstration I will use the Achievements view controller in my app. This is where you can see the achievements that you get in the app, the badges, the points, etc.
I prefer to create the interface elements in a separate class so I that my ViewController remains as clean as possible. Here I have the AchivementsViewController and the AchievementsViewControllerInterfaceTool.
The AchievementsViewController.h is defined as follows:
#import <UIKit/UIKit.h> #import "AchievementsViewControllerInterfaceTool.h" @interface AchievementsViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> @property (nonatomic, strong) UILabel *lblTest; @property (nonatomic, strong) UITableView *tableView; @end
The AchievementsViewControllerInterfaceTool.h is defined as follows:
#import <Foundation/Foundation.h> #import "AchievementsViewController" @class AchievementsViewController; @interface AchievementsViewControllerInterfaceTool : NSObject @property (nonatomic, strong) AchievementsViewController* controller; -(id)initWithController:(AchievementsViewController*)controller; -(void)AddTestLabel; -(void)AddTableView; @end
Since both classes will reference one another (thus creating a circular dependency), in the interface tool I will add a forward declaration to the AchievementsViewController class: @class AchievementsViewController.
I will also add a table view using this class, but here I will show only how to add a UILabel to the view.
This is how AchievementsViewControllerInterfaceTool.m looks like:
I will also add a table view using this class, but here I will show only how to add a UILabel to the view.
This is how AchievementsViewControllerInterfaceTool.m looks like:
#import "AchievementsViewControllerInterfaceTool.h"
@implementation AchievementsViewControllerInterfaceTool
@synthesize controller = _controller;
-(id)initWithController:(AchievementsViewController *)controller
{
self = [super init];
if (self) {
_controller = controller;
}
return self;
}
-(void)AddTestLabel
{
_controller.lblTest = [[[UILabel alloc] init] autorelease];
_controller.lblTest.text = @"Achievements View Controller";
_controller.lblTest.translatesAutoresizingMaskIntoConstraints = NO;
[_controller.view addSubview:_controller.lblTest];
UILabel *lbl = _controller.lblTest;
NSArray * constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-100-[lbl]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(lbl)];
[_controller.view addConstraints:constraints];
NSLayoutConstraint *c1 = [NSLayoutConstraint constraintWithItem:lbl
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:lbl.superview
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0];
[_controller.view addConstraint:c1];
}
I have created a constructor that takes as parameter a reference to the AchievementsViewController and assigns it to our internal variable, _controller.
In the first part of the AddTestLabel method I instantiate the UILabel lblTest and set the property translatesAutoresizingMaskIntoConstraints to NO. For more information about this property you can check the official documentation here.
I then define UILabel *lbl = _controller.lblTest. This is because in the next statement I have to define the visual format for the NSLayoutConstraint: "V:|-100-[lbl]". This means that I will set the label 100 spaces from the top of the superview. The superview is marked by the "|" character.
In the next constraint (c1) I set the label at the center of the superview, on the X axis only.
In the first part of the AddTestLabel method I instantiate the UILabel lblTest and set the property translatesAutoresizingMaskIntoConstraints to NO. For more information about this property you can check the official documentation here.
I then define UILabel *lbl = _controller.lblTest. This is because in the next statement I have to define the visual format for the NSLayoutConstraint: "V:|-100-[lbl]". This means that I will set the label 100 spaces from the top of the superview. The superview is marked by the "|" character.
In the next constraint (c1) I set the label at the center of the superview, on the X axis only.