Raj
Raj

Reputation: 67

how to do uilabel programmatically in auto layout

I am doing a project in auto layout in Xcode 6, I am adding a label programmatically its working perfectly in 4s,5,5s but in 6 and 6 plus is not working. can anyone help me, I am new to auto layout.Below is my coding.

UIScrollView *scroll = [[UIScrollView alloc]init];
[scroll setTranslatesAutoresizingMaskIntoConstraints:NO];
scroll.contentSize=CGSizeMake(480, 600);

[centerView addSubview:scroll];

NSDictionary *scrolldic = @{@"scrollview":scroll};

NSArray *scroll_H = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[scrollview(480)]" options:0 metrics:Nil views:scrolldic];

NSArray *scroll_V = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[scrollview(480)]" options:0 metrics:Nil views:scrolldic];

[scroll addConstraints:scroll_H];
[scroll addConstraints:scroll_V];
NSArray *scroll_posH = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[scrollview]" options:0 metrics:Nil views:scrolldic];

NSArray *scroll_posV = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[scrollview]" options:0 metrics:Nil views:scrolldic];


[self.view addConstraints:scroll_posH];
[self.view addConstraints:scroll_posV];
UILabel *header = [[UILabel alloc]init];
[header setTranslatesAutoresizingMaskIntoConstraints:NO];
header.backgroundColor = [UIColor blueColor];


 [scroll addSubview:header];

NSDictionary *headerdic = @{@"header":header};

NSArray *header_H = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[header(150)]" options:0 metrics:Nil views:headerdic];

 NSArray *header_V = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[header(30)]" options:0 metrics:Nil views:headerdic];

[header addConstraints:header_H];
[header addConstraints:header_V];

 NSArray *header_posH = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-80-[header]" options:0 metrics:Nil views:headerdic];

 NSArray *header_posV = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[header]" options:0 metrics:Nil views:headerdic];


[self.view addConstraints:header_posH];
[self.view addConstraints:header_posV];

enter image description here enter image description here

see the above image in 4s label is in center is correct , but in 6 it move to some left, what is the problem can any one help me.

Upvotes: 1

Views: 6025

Answers (3)

Catalina T.
Catalina T.

Reputation: 3494

To get it to work, it is also important how you want the layout to look on different devices. Should the label always have the width 150 and be centered or should it always have a 80 left and right padding?

This is what you have to decide but the constraints would look like this:

First case (same width and centered) :

NSLayoutConstraint *centerXConstraint = [NSLayoutConstraint constraintWithItem:header attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem: scroll attribute:NSLayoutAttributeCenterX multiplier:1.f constant:0];
[scroll addConstraint:centerXConstraint];

Second case (keep the padding between devices):

[scroll addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-leftPadding-[header]-leftPadding-|" options:0 metrics:@{ @"leftPadding": @(80) } views:@{ @"header": header }]];

Let me know hot it goes or if you need more help.

Upvotes: 1

sam_smith
sam_smith

Reputation: 6093

The issue seems to be that you have hard coded the values in. This is fine for iPhone 4 and 5 as they both have screens with width of 320. This means your hard coded value of 80 keeps it in the middle.

iPhone 6 though has a wider screen

iPhone 4 and 5

|---80---|--150--|---90---|

You can see this with a screenshot of your screenshot above:

enter image description here

Here I have added two green lines both the same length, although you think your label is in the middle on iPhone 4 and 5 it actually isn't.

What you need to do is one of two things:

  1. Use NSLayoutConstraints to fix the view in the middle instead of setting values. There are various layout constraints that put it in the middle.

You can use centreX for this

NSLayoutConstraint * centreConstraint = [NSLayoutConstraint constraintWithItem:self.contentView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:_yourLabel attribute:**NSLayoutAttributeCenterX** multiplier:1.0 constant:0];

Then add this constraint (NSLayoutConstraint can be quite fiddly so make sure you test it as this might not work)

This sets the label in the middle of the screen (hence the centreX - meaning centre of the x-axis)

  1. The other way, not recommended if you are trying to have both landscape and portrait orientations, would be to calculate the width of the screen and so enter an accurate half way padding value.

You can calculate the width of the screen with

[UIScreen mainScreen].bounds.size.width

Then you can calculate the value you need it to be Eg in your case it would be

// Your label is 150 pixels wide so the space on each side is the width less 150 but half as you have the same amount on each side.
([UIScreen mainScreen].bounds.size.width - 150)/2

This is a way to simply calculate the value needed and is not as good as using NSLayoutConstraint. It is much simpler but much less versatile. I only include it for completeness.

My advice, look on some tutorials for NSLayoutConstraints this one is good and get better understanding of what you are constraining.

Upvotes: 0

Asadullah Ali
Asadullah Ali

Reputation: 1064

Try adding your constraint like this

NSLayoutConstraint *leadingConstraint= [NSLayoutConstraint constraintWithItem:self.contentView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:_yourLabel attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0];
NSLayoutConstraint *topConstraint= [NSLayoutConstraint constraintWithItem:self.contentView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_yourLabel attribute:NSLayoutAttributeTop multiplier:1.0 constant:0];
[self.contentView addConstraints:@[leadingConstraint,topConstraint]];

Upvotes: 0

Related Questions