Reputation: 8144
I'm trying to learn Visual format language and in this case I want two button next each other in the top of the view.
This is my code but nothing appears?
UIButton *button1 = [[UIButton alloc] init];
[button1 setBackgroundColor:[UIColor blueColor]];
UIButton *button2 = [[UIButton alloc] init];
[button2 setBackgroundColor:[UIColor redColor]];
NSDictionary *views = NSDictionaryOfVariableBindings(button1, button2);
NSLog(@"%@", [views allKeys]);
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"[button1(==button2)]" options:0 metrics:Nil views:views];
[self.view addSubview:button1];
[self.view addSubview:button2];
[self.view addConstraints:constraints];
Thanks to the answer this is now my code:
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeSystem];
button1.translatesAutoresizingMaskIntoConstraints = NO;
[button1 setTitle:@"Button" forState:UIControlStateNormal];
[button1 setBackgroundColor:[UIColor redColor]];
[self.view addSubview:button1];
UIButton *button2 = [UIButton buttonWithType:UIButtonTypeSystem];
button2.translatesAutoresizingMaskIntoConstraints = NO;
[button2 setTitle:@"Button" forState:UIControlStateNormal];
[button2 setBackgroundColor:[UIColor blueColor]];
[self.view addSubview:button2];
NSDictionary *views = NSDictionaryOfVariableBindings(button1, button2);
NSString *const kHConstraint = @"|-[button1(==button2)]-[button2]-|";
NSString *const kVConstraint = @"V:|-[button1(==44)]";
NSString *const kVConstraint2 = @"V:|-[button2(==44)]";
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:kHConstraint options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:kVConstraint options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:kVConstraint2 options:0 metrics:nil views:views]];
I am wandering if I could combine the two Vertical constraints into one?
Yes this is possible by using the option NSLayoutFormatAlignAllTop:
NSDictionary *views = NSDictionaryOfVariableBindings(button1, button2);
NSString *const kHConstraint = @"H:|-[button1(==button2)]-[button2]-|";
NSString *const kVConstraint = @"V:|-[button1(==button2)]";
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:kHConstraint options:NSLayoutFormatAlignAllTop metrics:metrics views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:kVConstraint options:0 metrics:metrics views:views]];
Great article from:@jrturton and can be found here
Upvotes: 2
Views: 417
Reputation: 119242
You need to turn off autoresizing for the two buttons:
button1.translatesAutoresizingMaskIntoConstraints = NO;
button2.translatesAutoresizingMaskIntoConstraints = NO;
You have to specify enough constraints for the system to determine height, width and position for each subview. The default frame otherwise is CGRectZero
which will be invisible.
As a minimum, I'd suggest the following VFL statements to give you the layout you need:
@"V:|-[button1(==44)]"
This gives your button1 a height of 44, and positions it a standard inset from the top of the superview.
@"V:|[button2(==44)]"
This does the same to button 2. You can also achieve this by alignment options in the horizontal layout, but that will confuse things for the purposes of this answer.
@"|-[button1(==button2)]-[button2]-|"
This makes the buttons equal width, and also insets them from the superview's edges.
I have written about VFL at some length here which will hopefully help with your understanding.
Upvotes: 3