AutoLayout to keep view sizes proportional

一曲冷凌霜 提交于 2019-11-27 18:41:49

This can be resolved by adding one more dummy view(dummyView) with its constraints set to Fixed width, height and aligned to centerX of Superview.Then add left view and right view Horizontal spacing constraint to dummyView.

I'm probably late in coming up with a solution but this can actually be made very easily in IB.

First, add a UIView and pin in to all four edges of the superview.

Then, Add your first subview and position it accordingly (ig : x = 0, y = 0, height = fixed height, width = The width you would like relative to the UIView we pinned to all four edges).

Select both the UIView and the first subview and add an Equal Widths constraint. Of course, this will show you an error in positioning in the autolayout, but that's OK because this is not (yet) what you want.

Now comes the trick : select the Equal Widths constraint and edit the Multiplier to be the ratio you want (eg : 1:4 if you want the first subview to be 1/4 of the UIView). Repeat steps for the second subview and Tadaaaaaa !

I'm new to autolayout but came across your question and thought it would be a good challenge. (That's my caveat in case this isn't the ideal solution!)

You'll need to add the width constraints in code. I achieved this by firstly adding the two views in the NIB without width constraints. These are the constraints for the first (left) view:

These are the constraints I had for the second (right) view:

This leaves an extra constraint you don't want on the second view - leading space between superview and the second view as shown below:

You can't remove that constraint in IB as it would leave an ambiguous layout (as we don't have widths on the subviews). However you can remove it in code. Firstly, set up an outlet for it and connect it in IB:

@property (nonatomic, strong) IBOutlet NSLayoutConstraint *view2superviewLeadingConstraint;

Then, in your view controller's viewDidLoad, you can remove it using:

[self.view removeConstraint:self.view2superviewLeadingConstraint];

Finally, add the width constraints. The key here is the multiplier parameter to dicate what percentage you want the widths to be based on the superview width. Also note that you have to set the constant parameters to equal the leading/trailing totals set up in IB:

NSLayoutConstraint *constraint1 = [NSLayoutConstraint constraintWithItem:self.view1 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:0.3 constant:-20];
[self.view addConstraint:constraint1];

NSLayoutConstraint *constraint2 = [NSLayoutConstraint constraintWithItem:self.view2 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:0.7 constant:-40];
[self.view addConstraint:constraint2];

Just select the aspect ratio :

As others have mentioned, the key is setting a multiplier on the "Pin Widths Equally" constraint so that the views widths end up being a multiple of each other. XCode 5.1 should add the ability to set this in Interface Builder, but until then you've got another option besides setting it in code. If you create the "Pin Widths Equally" constraint, then go to the Identity Inspector in the Utilities Panel on the right, then look for "User Defined Runtime Attributes". Add a new attribute with key path "multiplier", type "number", and value equal to your desired ratio.

This won't be reflected in Interface Builder, but will apply when your view is used.

  1. Remove the two width constraints in code, or lessen their priorities in IB, otherwise you are over-constrained.
  2. Add a constraint to describe the width ratio between the green view and blue view, in code:

    // Assuming the ratio you want is green_view_width : blue_view_width = 1 : 2
    NSLayoutConstraint *c = [NSLayoutConstraint constraintWithItem:greenView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeWidth multiplier:0.5f constant:0.f];
    [commonSuperview addConstraint:c];
    

It's now possible in XCode 6 with the aspect ratio property

Eugene Braginets

In Interface Builder drag the view with right button (just a bit to display black popup).
In popup menu select Aspect Ratio.

I'm not sure how familiar you are with auto-layout, so apologies if this is stuff you already know:

When using auto-layout it's possible to assign several constraints to the same property. Under certain circumstances these constraints can contradict each other. This is what's causing the warning you're seeing.

It looks from the screen-grab you posted that you've set several constraints to be explicit - for example, your green view on the left has a constraint that says "Width (90)", which means the width must be equal to 90 points exactly.

It's unclear from the screenshot alone what your other constraints are mapped to, but what's probably happening here is these explicit constraints are causing problems - you have autoresizing constraints that say the views should expand or contract to fit their available area, but those same views have constraints that require them to be an exact width.

This can be fixed in a number of ways - you can either remove those explicit width constraints on your views, or you can change their priority (by default constraints are 'required', but you can change them to be optional).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!