iOS Autolayout proportionally resize UIViews?

2020-04-11 18:27发布

I'm trying to learn Autolayout, so I'm reading through tutorials and also messing around with some UIViews just to see what I can get them to do. I'm wondering how I would accomplish something like the picture below on the transition from portrait to landscape with autolayout? I thought, for example, that if I pinned the yellow to the top of the view, the blue to the yellow, the orange to the blue, and the orange to the bottom, they would resize proportionally, maintaining the 20 pixels between each other and the top and bottom of the view. But the blue box, for example, won't let me remove it's strut to the top of the view, even though it's pinned to the yellow view above it, so it's pushing everything down and off the screen in landscape. I know you can pin heights and widths equally to get them to resize, but is there any way to resize things proportionally, maintaining the spacing between them? enter image description here

2条回答
劳资没心,怎么记你
2楼-- · 2020-04-11 19:08

It can be frustrating to make constraints in Interface Builder, and Interface Builder can't yet make constraints with multipliers, such as blue.height = red.height * 0.5. They're all easy to make in code, though.

I used Interface Builder to create and color the UIViews, so first I want to remove all the constraints that Interface Builder created.

// in UIViewController.m
[self.view removeConstraints:self.view.constraints] ;

I'll create many constraints using constraintsWithVisualFormat:options:metrics:views:, so I create a dictionary of pointers to the 5 UIViews, and create an NSMutableArray to hold the constraints.

NSDictionary* views = NSDictionaryOfVariableBindings(black, red, yellow, blue, orange) ;
NSMutableArray* constraints = [NSMutableArray new] ;

Then I create the constraints that position the UIViews and indicate views that have the same widths & heights.

[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[black]-[yellow]-|"  options:0  metrics:nil  views:views]] ;
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[red(==black)]-[blue(==yellow)]-|"  options:0  metrics:nil  views:views]] ;
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[orange]-|"  options:0  metrics:nil  views:views]] ;
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[black]-[red(==black)]-[orange]-|"  options:0  metrics:nil  views:views]] ;
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[yellow]-[blue]-[orange]-|"  options:0  metrics:nil  views:views]] ;

And finally I create the constraints with multipliers, and add all of the constraints.

[constraints addObject:[NSLayoutConstraint constraintWithItem:orange  attribute:NSLayoutAttributeHeight  relatedBy:NSLayoutRelationEqual  toItem:black  attribute:NSLayoutAttributeHeight  multiplier:0.5  constant:0]] ;
[constraints addObject:[NSLayoutConstraint constraintWithItem:yellow  attribute:NSLayoutAttributeHeight  relatedBy:NSLayoutRelationEqual  toItem:black  attribute:NSLayoutAttributeHeight  multiplier:1.5  constant:0]] ;
[constraints addObject:[NSLayoutConstraint constraintWithItem:yellow  attribute:NSLayoutAttributeWidth  relatedBy:NSLayoutRelationEqual  toItem:black  attribute:NSLayoutAttributeWidth  multiplier:1.5  constant:0]] ;
[self.view addConstraints:constraints] ;
查看更多
▲ chillily
3楼-- · 2020-04-11 19:27

You can give proportional height or width constraint by following these steps.

1) First give an equal height or width constraint what ever you want to give according to requirements.

2) Double click the constraint on the right pane or click on the "Edit" on the right side of the constraint.

3) Change the multiplier like this. If you have added equal width constraint from a view of width 100 to a view of width 150 then you enter multiplier 150:100.

4) You need to make sure there will not be any warning regarding this constraint otherwise you need to change the multiplier like 100:150.

5) This happens because sometimes when you give equal width or height constraint the first view will be the view itself and sometimes the first view will be the other view. This totally depends upon the rest of the constraint you set for the other view.

6) Now when the constraint is applied correctly apply other constraints and check.

Thank you.

查看更多
登录 后发表回答