Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
622 views
in Technique[技术] by (71.8m points)

swift - Autolayout Contraints for a View from XIB

I am loading a view (shaped a circle) from a circle. I want to make sure, the circle's size adapts to various screen sizes. So far I tried placing the view inside another view, pinning the margins to the superview and then setting the superview's aspect ratio to 1:1. This gives me a circle. However, now, I want to change its size. Currently, the superview's size is specified by another subview in it, a label. Depending on the contents of the label, the superview's size changes (I have set the label's font size to Autoshrink). If I try to add a constant to the margin constraints it works, but looks the same size across different screen sizes. Also, I tried adding a multiplier, while the multiplier works for trailing and bottom margins, top and leading margins don't get affected by setting the multiplier. Below is a screenshot of the IB (Today View is the shape in the question). enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You have a good start - aligning both center X & Y, 1:1 ratio. All you need to add is two sets of top/bottom and leading/trailing constraints with different priorities. Here's an example, which combined with the three constraints you have, would center a view in all orientations with a 10 point border along the narrower axis:

Priority == 750

  • Top == 10 points
  • Bottom == 10 Points
  • Leading == 10 points
  • Trailing == 10 points

Priority == 1000

  • Top >= 10 points
  • Bottom >= 10 Points
  • Leading >= 10 points
  • Trailing >= 10 points

You may see errors/warnings while doing this because IB doesn't know how to render it, but once you've completed this, you'll have what you need.

EDIT:

From memory, there are points and pixels. When and where possible, try to think in terms of points. About the only time you may wish to think in terms of pixels is with images. (There may be other measurements of graphics, but again, I'm writing from memory.)

Points should be consistent across device size - so if you have a 100x100 square in a 4 inch iPhone screen, it will be the same size on a 12.9 inch iPad Pro.

More importantly, the margins can be set the same using auto layout. A 25 point margin will be the same on both of those screen. So in my example above, you will get pretty much the largest rectangle possible across all devices since you are setting margins, not view size.

I did a dive into screen sizes last year, and these are the current screen sizes:

//iPad Pro        1366x1024
//iPad            1024x768
//iPad Mini       1024x468
//iPhone 6 Plus   736x414
//iPhone 6        677x375
//iPhone 5        568x320
//iPhone 4        480x320

So based on this the above constraints would yield a 300x300 square on an iPhone 4 (iPhone SE also) as the narrowest axis will be 320 less two 10 point margins. And on an iPad Pro 12.9 inch it will be a 1004x1004 square.

When you create constraints in code, you can also create a layoutMarginGuide with this code:

    let margins = view.layoutMarginsGuide

This should be the same thing as keeping the "contain to margins" checkbox checked in IB. Essentially this is the recommended size of margins for each device. (I believe this should also include the status bar, tab and navigation bars, and even the iPhone "phone call top banner (sic)". But I've had some issues with this so YMMV.)

EDIT 2:

Putting this all together, what you are defining through "auto layout" is a very fluid way of maximizing the size of a square (or in your case, a square turned into a circle). By setting two sets of margins, one set equal to but with a high priority, you are letting auto layout know that it may break this over required constraints. The second set with greater than or equal to values is required.

Thus, in a 480x320 device, the top/bottom margin constraints that cannot be met ("equal to") can be broken, and in landscape the leading/trailing ones that cannot be met will be broken. Remember, you already set the center X/Y, so the view will be centered, and you set the 1:1 ratio so it will be square. (As long as you did not touch the priorities - the default is required.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...