0

I know there is are similar topics, but i cant figure out how to do simple thing, for example, set view frame programmatically with Auto Layout constraints. Its pretty easy to do with Storyboard, but when i try to learn about NSLayourConstraint i realise that i'm not understand topic.

Consider that we have UIView and 3 buttons. First button at top have 3 constraints (leading and trailing, and to top of a view). Other 2 buttons centered horizontally with that button and have equal widths. its pretty easy layout, i upload screenshot:

enter image description here

I have read about visual format language, but what i cant understand is - how to create constraint, for example, that relay to top (or trailing-leading)? Like following: enter image description here

Task look pretty simple but still, i did not found a way how to do that programmatically with NSLayoutConstraint. Could you please provide a solution? Thanks.

1 Answer 1

1

Here's a solution (should go in -viewDidLoad). There are a a couple of things to note:

Firstly, VFL doesn't allow you to create all possible types of constraint. In particular, centering needs to be done with the +constraintWithItem: class method on NSLayoutConstraint.

Secondly, as noted in the comments, you could just use hardcoded left and right pad values in the horizontal VFL string to achieve the centering, but this might cause problems if you need to support different device sizes.

Thirdly, the call to -setTranslatesAutoresizingMaskIntoConstraints: is critical. Programmatic Autolayout will completely fail to work if you forget this. Also you need ensure all views are added to their superviews before setting up constraints, otherwise any constraint string referencing a superview will cause a crash

NSArray *names = @[@"button1",@"button2",@"button3"];
NSMutableDictionary *views = [[NSMutableDictionary alloc]init];

for(NSUInteger i=0;i<3;i++) {
    UIButton *b = [[UIButton alloc]init];
    NSString *name = names[i];
    [b setTitle:name forState:UIControlStateNormal];
    views[name] = b;
    [b setBackgroundColor:[UIColor redColor]];
    [b setTranslatesAutoresizingMaskIntoConstraints:false];
    [self.view addSubview:b];
}
//List of values to be used in the constraints
NSDictionary *metrics = @{
  @"buttonWidth":@150,
  @"bHeight":@50, //button height
  @"topPad":@100,
  @"vPad":@20 //vertical padding
};

//Horizontal VFL string (repeated for all rows).

for (NSString *buttonName in views.allKeys) {
    NSString *horizontalConstraintString = [NSString stringWithFormat:@"|-(>=0)-[%@(buttonWidth)]-(>=0)-|",buttonName];
    NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:horizontalConstraintString options:0 metrics:metrics views:views];
    [self.view addConstraints:horizontalConstraints];
    //Can't do centering with VFL - have to use constructor instead. You could also hardcode left and right padding in the VFL string above, but this will make it harder to deal with different screen sizes
    NSLayoutConstraint *centerConstraint = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:views[buttonName] attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0];

    [self.view addConstraint:centerConstraint];
}

//Vertical VFL (vertical spacing of all buttons)

NSString *verticalConstraintString = @"V:|-topPad-[button1(bHeight)]-vPad-[button2(bHeight)]-vPad-[button3(bHeight)]-(>=0)-|";
NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:verticalConstraintString options:0 metrics:metrics views:views];

[self.view addConstraints:verticalConstraints];
[self.view layoutIfNeeded];
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you Rich Tolley now i understand. Could you provide link where i can learn that in more detail?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.