iOS constraints not updating as expected - ios

I have a superview with circle view and a holderview that contains 3 labels as subview and is centred to the superview as seen in image
I have added constraints to the 3 labels with respect to holderview and also added constraints to holderview with respect to superview
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(titleLabel);
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"|-[titleLabel]-|"
options:0
metrics:nil
views:viewsDictionary];
[holderView addConstraints:constraints];
viewsDictionary = NSDictionaryOfVariableBindings(setLabel);
constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"|-[setLabel]-|"
options: 0
metrics:nil
views:viewsDictionary];
[holderView addConstraints:constraints];
viewsDictionary = NSDictionaryOfVariableBindings(repLabel);
constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"|-[repLabel]-|"
options:0
metrics:nil
views:viewsDictionary];
[holderView addConstraints:constraints];
viewsDictionary = NSDictionaryOfVariableBindings(titleLabel, setLabel, repLabel);
constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-[titleLabel]-0-[setLabel]-0-[repLabel]-|"
options:0
metrics:nil
views:viewsDictionary];
[holderView addConstraints:constraints];
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(_labelView);
NSArray *constraints =[NSLayoutConstraint constraintsWithVisualFormat:#"|-[_labelView]-|"
options:0
metrics:nil
views:viewsDictionary];
[self addConstraints:constraints];
There is a feature in app where the circle shrinks. I want the holderview and its subivews to shrink dynamically. Adding the constraints works for holderview but the subviews get misaligned.
To shrink i update the frame size of the holderview as the superview frame changes.
Can anyone point out the mistakes and guide me to proper solution ?

Using auto layout and changing frame property messes up things.
Create oultest to the constraints that you want to change or animate
__weak IBOutlet UIView *settingsView;
__weak IBOutlet NSLayoutConstraint *settingsBottomConstraint;
__weak IBOutlet NSLayoutConstraint *settingsViewHeightConstraint;
Update the constrains(Never the frame!)
settingsBottomConstraint.constant = - settingsViewHeightConstraint.constant;
[settingsView setNeedsUpdateConstraints];
[settingsView layoutIfNeeded];
isSettingsHidden = YES;
Recently I have worked with animation of views with autolayout and you can find your answer here
Auto Layout constraint change does not animate

You can also use the function updateConstraints.
[settingsView updateConstraints];

Related

need help in autolayout top layout guide, UIscrollView, UIImageView

I am working on a top sticked streach header.
My setup:
UIScrollView
-UIView(a container)
-UIImageView
-UIView(subContent view)
What i want:
Stick UIImageView to top layout guide.
UIImageView height is 100 - 250. That is UIImageView height is initialise with 250, but can not be less than 100.
0 top space in between UIImageView and subContentView.
So when user scroll towards bottom, UIImageView will gradually minimise and will no more minimise as soon as it's height reaches 100(minimum height).
BUT subContentView must not overlap my UIImageView and be able to scroll till end (accurate content size/ offset)
What i am able to do is:
i am able to stick UIImageView to top based on layout guide.
I am also able to acheive height range of UIImageView on scroll top or bottom (increase and decrease height).
BUT i am not able to stop UIImageView from being overlapping by my subContentView.
That is when i scroll to bottom my UIImageView remains stick to top and gradually decreases it's size, at the moment it reaches to height 100,(i am still scrolling bottom) my subContentView starts overlapping my UIImageVIew.
How ever it makes sense as i have no set constraints from top layout guide to subcontent view.
some thing like:
format = #"V:|[topGuide]-**some dynamic value based on UIImageViewHeight**-[subContentView]";
How do i achieve this.
Please help me i am working on it from a day, and finally i decided to ask.
my code:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.title = #"Programmatically";
NSMutableDictionary* views = [NSMutableDictionary new];
views[#"super"] = self.view;
views[#"topGuide"] = self.topLayoutGuide; // The bottom of the navigation bar, if a navigation bar is visible. The bottom of the status bar, if only a status bar is visible .. etc...
//Create the ScrollView
UIScrollView* scrollView = [UIScrollView new];
scrollView.delegate = self;
scrollView.translatesAutoresizingMaskIntoConstraints = NO; //we are using auto layout
self.automaticallyAdjustsScrollViewInsets = NO;
[self.view addSubview:scrollView];
views[#"scrollView"] = scrollView;
//Create the scrollview contentview
UIView* contentView = [UIView new];
[contentView setBackgroundColor:[UIColor yellowColor]];
contentView.translatesAutoresizingMaskIntoConstraints = NO; //we are using auto layout
[scrollView addSubview:contentView];
views[#"contentView"] = contentView;
//Add the image view and other addtional views to the content view
topImageView = [[WAPlayerDetailHeader alloc] initWithFrame:CGRectZero andImage:nil];
topImageView.translatesAutoresizingMaskIntoConstraints = NO; //we are using auto layout
topImageView.contentMode = UIViewContentModeScaleAspectFill;
topImageView.clipsToBounds = YES;
[contentView addSubview:topImageView];
views[#"topImageView"] = topImageView;
//Add other content to the scrollable view
UIView* subContentView = [UIView new];
[subContentView setBackgroundColor:[UIColor redColor]];
subContentView.translatesAutoresizingMaskIntoConstraints = NO; //we are using auto layout
[contentView addSubview:subContentView];
views[#"subContentView"] = subContentView;
//Now Let's do the layout
NSArray* constraints;
NSString* format;
NSDictionary* metrics = #{#"imageHeight" : #250.0};
//======== ScrollView should take all available space ========
format = #"|-0-[scrollView]-0-|";
constraints = [NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:views];
[self.view addConstraints:constraints];
format = #"V:[topGuide]-0-[scrollView]-0-|";
constraints = [NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:views];
[self.view addConstraints:constraints];
//======== ScrollView Content should tie to all four edges of the scrollview ========
format = #"|-0-[contentView]-0-|";
constraints = [NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:views];
[scrollView addConstraints:constraints];
format = #"V:|-0-[contentView]-0-|";
constraints = [NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:views];
[scrollView addConstraints:constraints];
// ========== Layout the image horizontally
format = #"|-0-[topImageView(==super)]-0-|"; // with trick to force content width
constraints = [NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:views];
[self.view addConstraints:constraints];
// ========== Put the sub view height, and leave room for image
format = #"|-0-[subContentView]-0-|";
constraints = [NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:views];
[scrollView addConstraints:constraints];
// we leave some space between the top for the image view
format = #"V:|-imageHeight-[subContentView(1000)]-0-|"; /*the view height is set to 700 for the example in order to have enough content */
constraints = [NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:metrics views:views];
[scrollView addConstraints:constraints];
// Start of the magic
format = #"V:[topImageView]-0-[subContentView]"; // image view bottom is subcontent top
constraints = [NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:views];
[contentView addConstraints:constraints];
// image view top is the top layout
format = #"V:|[topGuide]-0-[topImageView(>=100)]";
constraints = [NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:views];
[self.view addConstraints:constraints];
//Optional stuff, Add The A view
aView = [[WAPlayerDetailHeader alloc] initWithFrame:CGRectZero andImage:nil];
[aView setAlpha:1.0];
aView.translatesAutoresizingMaskIntoConstraints = NO; //we are using auto layout
aView.backgroundColor = [UIColor colorWithRed:0.79 green:0.9 blue:0.69 alpha:1];
[subContentView addSubview:aView];
views[#"aView"] = aView;
format = #"|[aView]|";
constraints = [NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:views];
[subContentView addConstraints:constraints];
format = #"V:|-[aView(127)]-5-|";
constraints = [NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:views];
[subContentView addConstraints:constraints];
}
this is what happening video demo
i am following this code from this location
i have upload on git download and you can see

add subviews generated by autoayout to a parent view

This is my very first program in autolayout.
Basic problem: i am not able to add subviews(a uibutton and a uilabel) to a superview(a containerview).Subviews are just out of bond of superview or say not clipped.
I have added commented in detail to be better understanding of code.
What i want:
i dont care whereever containerview is but i want both subviews to be add in containerview with 0 padding from all sides.
- (void)viewDidLoad {
[super viewDidLoad];
**//create a uibutton with dynamic text(MAX_WIDTH=500, height = 60) and uilabel of fixed size(60, 60).Done
//create pin of fixed 2 pixes between UIButton and UILabel.Done
//put above created views in container view, it will max to 562 width and fix 60 height, so UIButton and UIlabel should fill container view with no top, bottom, left and right.Fail**
//this will be containing my button and my label
UIView *superview = self.view;
UIView *containerView = [UIView new];
[containerView setBackgroundColor:[UIColor blackColor]];
[containerView setTranslatesAutoresizingMaskIntoConstraints:NO];
[superview addSubview:containerView];
//this will be containing my button and my label
UILabel *mylabel = [[UILabel alloc]init];
[mylabel setBackgroundColor:[UIColor redColor]];
[mylabel setTranslatesAutoresizingMaskIntoConstraints:NO];
mylabel.text = #"MyLabel";
UIButton *mybutton = [UIButton
buttonWithType:UIButtonTypeRoundedRect];
[mybutton setTitle:#"My Button ye ye yey yeyeyye yeyey"
forState:UIControlStateNormal];
[mybutton setTranslatesAutoresizingMaskIntoConstraints:NO];
[mybutton setBackgroundColor:[UIColor greenColor]];
[containerView addSubview:mylabel];
[containerView addSubview:mybutton];
NSDictionary * views = NSDictionaryOfVariableBindings(mybutton,mylabel);
//create pin of fixed 2 pixes between UIButton and UILabel.Done
NSArray * horizontalConstraintsforbuttons = [NSLayoutConstraint constraintsWithVisualFormat:#"H:[mybutton(<=500)]-2-[mylabel(60)]" options:0 metrics:nil views:views];
NSArray * heightConstraintforbutton = [NSLayoutConstraint constraintsWithVisualFormat:#"V:[mybutton(==60)]" options:0 metrics:nil views:views];
NSArray * heightConstraintforLabel = [NSLayoutConstraint constraintsWithVisualFormat:#"V:[mylabel(==60)]" options:0 metrics:nil views:views];
[containerView addConstraints:horizontalConstraintsforbuttons];
[containerView addConstraints:heightConstraintforbutton];
[containerView addConstraints:heightConstraintforLabel];
//container view specific constraints//**it must be ideally <=562, but then this container view disappears, please hep to fix**
NSArray *widthConstraintForConstraint = [NSLayoutConstraint constraintsWithVisualFormat:#"H:[containerView(==560)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(containerView)];
NSArray *heightConstraint = [NSLayoutConstraint constraintsWithVisualFormat:#"V:[containerView(==60)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(containerView)];
[superview addConstraints:widthConstraintForConstraint];
[superview addConstraints:heightConstraint];
[superview addConstraint:[NSLayoutConstraint constraintWithItem:containerView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0]];
[superview addConstraint:[NSLayoutConstraint constraintWithItem:containerView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeCenterY multiplier:1.0f constant:0.0]];
}
Any suggestion? :)
The VFL for each of your subviews is missing a relationship with the parent view. Autolayout is assuming your constraints should be in relation to the top-level view — what you've defined as self.view.
Here's where your problem is.
NSDictionary * views = NSDictionaryOfVariableBindings(mybutton,mylabel);
//create pin of fixed 2 pixes between UIButton and UILabel.Done
NSArray * horizontalConstraintsforbuttons = [NSLayoutConstraint constraintsWithVisualFormat:#"H:[mybutton(<=500)]-2-[mylabel(60)]" options:0 metrics:nil views:views];
NSArray * heightConstraintforbutton = [NSLayoutConstraint constraintsWithVisualFormat:#"V:[mybutton(==60)]" options:0 metrics:nil views:views];
NSArray * heightConstraintforLabel = [NSLayoutConstraint constraintsWithVisualFormat
First, add your containerView to that dictionary so you can refer to it in VFL:
NSDictionary *views = NSDictionaryOfVariableBindings(mybutton,
mylabel,
containerView);
Then in your VFL, use the pipe operator (|) to tell autolayout to place your subviews in relation to their immediate parent.
NSArray * horizontalConstraintsforbuttons = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[mybutton(<=500)]-2-[mylabel(60)]" options:0 metrics:nil views:views];
NSArray * heightConstraintforbutton = [NSLayoutConstraint constraintsWithVisualFormat:#"V:[mybutton(==60)]|" options:0 metrics:nil views:views];
NSArray * heightConstraintforLabel = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[mylabel(==60)]|" options:0 metrics:nil views:views];
I'm not entirely sure what you're trying to do with the horizontal placement of those views, but this should get you back on track. I recommend reading this post on VFL, too.
Edit
I sort of see what you're trying to do now. First, base your values at 1x when working with VFL and autolayout. As an example, a width of 560 is larger than the largest possible iPhone screen:
NSArray *widthConstraintForConstraint = [NSLayoutConstraint constraintsWithVisualFormat:#"H:[containerView(==560)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(containerView)];
Let's pretend you just wanted containerView to match the width of the device. That would look like this:
#"H:|[containerView]|"
Those pipe operators outside the containerView are saying that you want the leading (left side) and trailing (right side) space of containerView to be flush with the superview.
Alternatively, let's say you wanted your view to be slightly smaller than the width of the device (560/2).
#"H:[containerView(==280)]"
You're already horizontally centering containerView elsewhere, so it'll appear in the center of it's superview.
Let's then assume you want your red label to (actually) have a width of 60 and your green button to have a width less than or equal to 250 (500/2). That would look like this:
#"H:|[mybutton(<=250)]-2-[mylabel(==60)]|"
Since these are subviews of containerView (and we told that to autolayout earlier), the pipe operators are saying you want
the leading space (left side) of mybutton to be flush with containerView.
the trailing space (right side) of mylabel to be flush with containerView.
Since mylabel has a width of 60, mybutton will be narrower (thanks to <=) to satisfy constraints, depending on the width of containerView.

how to avoid hardcoding with programmatic autolayout

I have an issue when using autolayout (I'm new to it) where, although my constraints function as expected (everything centered horizontally, vertical spacing as I want it), when I move to landscape orientation, the bottom button disappears.
I understand that this happens because I've constrained my objects based on a portrait orientation view, and this no longer applies when the height and width values shift as we move to landscape. I just don't really know how to account for these changes when changing orientation. Any advice?
code and screenshot below:
-(void)setConstraints {
[self.view removeConstraints:self.view.constraints];
UIButton *cameraButton = self.cameraButton;
UILabel *camera = self.videoLabel;
UIButton *libraryButton = self.libraryButton;
UILabel *library = self.libraryLabel;
NSDictionary *views = NSDictionaryOfVariableBindings(camera, cameraButton, libraryButton, library);
NSDictionary *metrics = #{#"horizontalSpacing":#500.0, #"verticalSpacing":#125};
//set up top button to be horizontally centered
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"|-[cameraButton]-|"
options:0
metrics:nil
views:views];
//set up top button vertical from top of superview
constraints = [constraints arrayByAddingObjectsFromArray:
[NSLayoutConstraint constraintsWithVisualFormat: #"V:|-175-[cameraButton]"
options:0
metrics:nil
views:views]];
//set up top button label to be horizontally centered
constraints = [constraints arrayByAddingObjectsFromArray:
[NSLayoutConstraint constraintsWithVisualFormat: #"|-[camera]-|"
options:0
metrics:nil
views:views]];
//set up second button to be horizontally centered
constraints = [constraints arrayByAddingObjectsFromArray:
[NSLayoutConstraint constraintsWithVisualFormat: #"|-[libraryButton]-|"
options:0
metrics:nil
views:views]];
//set up label for second button to be horizontally centered
constraints = [constraints arrayByAddingObjectsFromArray:
[NSLayoutConstraint constraintsWithVisualFormat: #"|-[library]-|"
options:0
metrics:nil
views:views]];
//set up vertical constraints by spacing ALL objects appropriately
constraints = [constraints arrayByAddingObjectsFromArray:
[NSLayoutConstraint constraintsWithVisualFormat: #"V:[cameraButton]-[camera]-verticalSpacing-[libraryButton]-[library]"
options:0
metrics:metrics
views:views]];
self.libraryLabel.textAlignment = NSTextAlignmentCenter;
self.videoLabel.textAlignment = NSTextAlignmentCenter;
self.libraryLabel.backgroundColor = [UIColor redColor];
[self.view addConstraints:constraints];
}
You are getting exactly what you asked for. If that isn't what you want, don't ask for that!
Think about your vertical constraints:
#"V:|-175-[cameraButton]"
#"V:[cameraButton]-[camera]-verticalSpacing-[libraryButton]-[library]"
That constitutes a single chain of constraints from the top down. Naturally, if the screen is shorter than your 175 plus your verticalSpacing plus the sizes and minimal spacings of the other views, the bottom view(s) will be off the bottom of the screen.
If that isn't what you want, change your design so that isn't what you get. For example, position some of your views from the top down and some of your views from the bottom up. Or allow some of your spaces to change as a percentage of the superview height.

App crashing while adding constraints programatically

I am using visual format to define constraints. The goal is to place a UIView at the bottom of the super view say self.view with height fixed as 40, and width automatically. I have done this using Storyboard but I am unable to do it programatically. Here is the code what I have written. The app is crashing if i am not giving a fixed width. It is crashing with the following constraint: "H:[redView]|". If I change this to "H:[redView(100)]", it works. I don't want to use self.bounds and get width from there. It should stick from left side of super view, bottom and right side of the view.
Please help!
NSDictionary *viewsDictionary = #{#"redView":self.redView};
NSArray *constraint_H = [NSLayoutConstraint constraintsWithVisualFormat:#"V:[redView(40)]"
options:0
metrics:nil
views:viewsDictionary];
NSArray *constraint_V = [NSLayoutConstraint constraintsWithVisualFormat:#"H:[redView]|"
options:0
metrics:nil
views:viewsDictionary];
// 3. Define the redView Position
NSArray *constraint_POS_V = [NSLayoutConstraint constraintsWithVisualFormat:#"V:[redView]|"
options:0
metrics:nil
views:viewsDictionary];
NSArray *constraint_POS_H = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[redView]"
options:0
metrics:nil
views:viewsDictionary];
[self.redView addConstraints:constraint_H];
[self.redView addConstraints:constraint_V];
[self.view addConstraints:constraint_POS_H];
[self.view addConstraints:constraint_POS_V];
You need to add redView to its super view first.
Also, the constraints are to be added to the superview, not redView.
[self.view addSubview:self.redView];
// create your constraints here
[self.view addConstraints:#[constraint_H, constraint_V, constraint_POS_V, constraint_POS_H]];
[self.view updateConstraintsIfNeeded];
In the visual constraints syntax the | refers to the parent view. The way you had that horizontal constraint before, adding it to the redview, it was interpreted as redview had a child, called the same, which obviously did not exist, so it crashed.
The vertical constraint works the way it is because it does not reference the parent view.
You could change your code a bit so that the constraints are more clear:
NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:[redView(40)]|" options:0 metrics:nil
views:viewsDictionary];
NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[redView]|" options:0 metrics:nil
views:viewsDictionary];
[self.view addConstraints:horizontalConstraints];
[self.view addConstraints:verticalConstraints];
Just remember you should always add the constraints for an UIView to it's superview.
Changing this line
[self.redView addConstraints:constraint_V];
with
[self.view addConstraints:constraint_V];
Solved myself. Thanks to me..:)
If you want to take the width of the view and apply it to red view, you only need to add a constraint like that:
NSArray *constraint_POS_H = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[redView]-|"
options:0
metrics:nil
views:viewsDictionary];

Using NSLayoutConstraint Visual Format to set width of items

I'm trying to get a hang of NSLayoutConstraints visual format and I am having a little trouble.
What I want is basically a simple UIView with two labels, one on the left, and one on the right, with heights equal to the height of the container, and the widths equal to 1/2 of the container width. The origin of the right label is aligned to the trailing of the left label.
| LEFT LABEL - RIGHT LABEL|
Anyway, here is my attempt:
self.leftLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.rightLabel.translatesAutoresizingMaskIntoConstraints = NO;
NSDictionary *views = #{ #"leftLabel" : self.leftLabel,
#"rightLabel" : self.rightLabel };
NSDictionary *metrics = #{ #"width" : #(CGRectGetWidth(self.frame) / 2) };
NSArray *constraints;
constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-[leftLabel]-|" options:0 metrics:metrics views:views];
[self addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-[rightLabel]-|" options:0 metrics:metrics views:views];
[self addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[leftLabel(width)]" options:0 metrics:metrics views:views];
[self addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-width-[rightLabel(width)]" options:0 metrics:metrics views:views];
[self addConstraints:constraints];
[self setNeedsUpdateConstraints];
[self updateConstraintsIfNeeded];
Unfortunately, the width of each label remains 0 after this executes. Any suggestions?
UPDATE
Here's the whole class:
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
self.leftLabel = [UILabel new];
self.rightLabel = [UILabel new];
self.loadingView = [[DDLoadingView alloc] init];
self.rightLabel.backgroundColor = [UIColor redColor];
self.leftLabel.backgroundColor = [UIColor redColor];
self.backgroundColor = [UIColor blackColor];
[self addSubview:self.leftLabel];
[self addSubview:self.rightLabel];
[self configureLayout];
}
return self;
}
- (void)configureLayout
{
self.leftLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.rightLabel.translatesAutoresizingMaskIntoConstraints = NO;
NSDictionary *views = #{ #"leftLabel" : self.leftLabel,
#"rightLabel" : self.rightLabel,
#"loadingView" : self.loadingView };
NSDictionary *metrics = #{ #"width" : #(CGRectGetWidth(self.frame) / 2) };
NSArray *constraints;
constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-[leftLabel]-|" options:0 metrics:metrics views:views];
[self addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-[rightLabel]-|" options:0 metrics:metrics views:views];
[self addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[leftLabel]-[rightLabel(==leftLabel)]-|" options:0 metrics:metrics views:views];
[self addConstraints:constraints];
[self setNeedsUpdateConstraints];
[self updateConstraintsIfNeeded];
}
You need to set the constraints to use the widths of the other views:
NSArray *constraints;
constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-[leftLabel]-|" options:0 metrics:metrics views:views];
[self addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-[rightLabel]-|" options:0 metrics:metrics views:views];
[self addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[leftLabel]-[rightLabel(==leftLabel)]-|" options:0 metrics:metrics views:views];
[self addConstraints:constraints];
The last constraint is saying make those two views the same width while pinning them to the left/right egdes of the superview. See the Equal Widths section of the docs
As discussed in the comments, you need to also make sure that the frame of the superview can accommodate the views themselves. |-[ will use the default insets of 20, using |-2- will give insets of 2. If the intrinsic height of the labels is more than the views height minus these insets your view isn't going to show. So you either need to reduce the insets or increase the height of the container.
If you want more information on AutoLayout I recommend the following series of blog posts by #jrturton - see the top of the article for other posts in the series. He's also got a great category on UIView to make adding constraints easier, I use this daily!

Resources