如何使用自动布局根据屏幕尺寸缩放边距?
想象一下,我有一个具有特定宽高比约束(这处理高度/底部约束)的 UIImageView,固定到 superview 的顶部,前导,尾随 5pt,在 100pt 中XIB/故事板中的宽度屏幕。这样,如果屏幕尺寸发生变化,图像视图可以相应缩放。
也就是说,在 100pt 宽度的屏幕中,边距间距为 5pt+5pt (10pt),图像占据 90pt(屏幕的 90%)。
不过我希望边距间距也能缩放。
我怎样才能做到这样,在更大的手机上,例如宽度为1000pt(之前的10倍),边距现在相应地为50pt+50pt(100pt),图像占据屏幕的剩余900pt,保留90%? (如果我们使水平约束不同,这可能会更加复杂,例如前导为 15pt,而尾随为 45pt。)
如果我们“正常”执行此操作而不缩放边距 pt,则前导/尾随的约束将为 5pt(在 1000pt 甚至 1000000pt 宽度的手机中总共 10pt!)。这不是我们通常想要的。
我们如何通过自动布局轻松实现这一点?我想到了班级规模,但这不适合我想要做的事情(以满足任何规模的所有设备)。
Imagine I have a UIImageView
with a certain aspect ratio constraint (this handles the height/bottom constraint), pinned to superview
's top, leading, trailing with 5pt in a 100pt width screen in XIB/storyboard. This way, if the screen size changes, the image view can scale accordingly.
That is 5pt+5pt (10pt) of margin spacing in a 100pt width screen, with image taking up 90pt (90% of the screen).
However I would like the margin spacing to be scaled as well.
How can I make it such that, on a bigger phone, e.g. with width 1000pt (10x previous), the margin will now correspondingly be 50pt+50pt (100pt) with the image taking up the remaining 900pt of the screen, retaining 90%? (This could be further complicated if we are making the horizontal constraints different, e..g. leading be 15pt while the trailing be 45pt.)
If we do it 'normally' without scaling the margin pt, the constraints of leading/trailing would be 5pt (for a total of 10pt in a 1000pt or even a 1000000pt width phone!). This is not what we usually want.
How can we achieve this easily with auto layout? I thought of class sizes but that does not fit what I am trying to do (to cater to all devices of any size).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
ASFAIK 没有办法定义相对于另一个视图宽度的前导或尾随约束。
要实现您想要的效果,您可以在
UIImageView
上设置以下约束:当您执行此操作时,水平边距图像的永远为屏幕尺寸的 10%。
编辑:
当您还需要相对上边距时,您可以将 UIImageView 放入另一个 UIView (具有灰色背景的那个)中,并使用以下约束:
如果您希望上边距与水平边距相同,则必须按如下方式计算:
verticalMultiplier =水平乘数/(2 *纵横比)
ASFAIK there is no way to define leading or trailing constraints relatively to another view's width.
To achieve what you want you can set the following constraints on the
UIImageView
:When you do this, the horizontal margins of the image will always be 10% of the screen size.
EDIT:
When you also need a relative top margin you could put the UIImageView into another UIView (the one with the gray background) and use the following constraints:
If you want to have a top margin that is the same as the horizontal margins, you have to calculate it like this:
verticalMultiplier = horizontalMultiplier / (2 * aspectRatio)
无论是在 Storyboard / IB 中布局还是通过代码完成,最简单的方法可能是使用水平堆栈视图,每侧都有一个(清晰的)“间隔”视图。
不过,您必须提前决定所需的比例。
也就是说,我们认为基于
100-pts
的总宽度,前导空格应为5-pts
...或25-pts
基于150-pts
...等等。所以我们的堆栈视图将有3个排列的子视图:
640:360
比例)将 LeftSpacer 的宽度限制为堆栈视图的宽度,乘数为
(左侧空间)/100
。将 RightSpacer 的宽度限制为堆栈视图的宽度,乘数为
(右侧空间)/100
。这里有两个例子。
顶部堆栈视图的左右间隔符均设置为 5/100。底部堆栈视图具有
Left: 5/100
和Right: 45/100
。在两个堆栈视图中,图像视图都设置为 640:360 宽高比(因为这是我方便使用的图像)。这是堆栈视图
Width: 100
的外观:顶部示例 - 两个间隔视图均为 5 点,图像视图为 90 点
底部示例 - 左侧间隔: 5 点,右:45 点,图像视图:50 点
和堆栈视图
宽度:200
:顶部示例 - 两个间隔视图都是10 点,图像视图为 180 点
底部示例 - 左侧间隔:10 点,右侧:90 点,图像视图:100 点
和堆栈视图
宽度:300
:顶部示例 - 两个间隔视图均为 15 点,图像视图均为 270 点
底部示例 -左间隔:15 点,右:135 点,图像视图:150 点
这是文档大纲:
和 Storyboard 源(如果您想检查它):
显然,这很容易在代码中复制。
如果出于某种原因,您不想使用堆栈视图,则可以在两个“侧面间隔视图”上使用前导/尾随和比例宽度约束进行本质上相同的操作,或者使其更轻量级,使用
ConstraintLayoutGuide
而不是清晰的视图。编辑 - 需要更多说明...
首先,我应该通过 ConstraintLayoutGuide 指定我指的是
UILayoutGuide
- 哎呀:(您概述的任务:
也可以描述为:
自动布局无法将前导锚点设置为超级视图宽度的百分比。
因此,传统上,我们使用清晰背景的“间隔”视图:
在 iOS 9 中,Apple 引入了
UILayoutGuide
(文档):这些不能添加到 Storyboard / IB 中,但可以在代码中使用,其方式与标准
UIView
大致相同。下面是一个简单的示例,它将“青色”视图和
UILayoutGuide
添加到“容器”视图,为青色视图提供 15% 的“前导空间”:结果 - 15-pts (15% )对于 100 磅“容器”视图(红色轮廓):
并且,如果我们将容器宽度更改为 200 点,我们将获得 30 点(15 %) 的前导空格:
Whether laying this out in Storyboard / IB or doing it via code, probably the easiest way is to use a horizontal stack view, with a (clear) "spacer" view on each side.
What you have to decide in advance, though, is the desired proportion.
That is, we say the leading space should be
5-pts
based on a total width of100-pts
... or25-pts
based on150-pts
... etc.So our stack view will have 3 arranged subviews:
640:360
ratio)Constrain the Width of the LeftSpacer to the width of the stack view, with a multiplier of
(left space)/100
.Constrain the Width of the RightSpacer to the width of the stack view, with a multiplier of
(right space)/100
.Here are two examples.
The Top stack view has both left and right spacers set to
5/100
. The Bottom stack view hasLeft: 5/100
andRight: 45/100
. In both stack views, the image view is set to640:360
aspect ratio (because that's the image I had handy).This is how it looks with stack view
Width: 100
:Top example - both spacer views are 5-pts, image view is 90-pts
Bottom example - left spacer: 5-pts, right: 45-pts, image view: 50-pts
and stack view
Width: 200
:Top example - both spacer views are 10-pts, image view is 180-pts
Bottom example - left spacer: 10-pts, right: 90-pts, image view: 100-pts
and stack view
Width: 300
:Top example - both spacer views are 15-pts, image view is 270-pts
Bottom example - left spacer: 15-pts, right: 135-pts, image view: 150-pts
This is the Document Outline:
and the Storyboard source if you want to inspect it:
Obviously, that would be straightforward to replicate in code.
If, for some reason, you don't want to use stack views, you could do essentially the same thing with leading/trailing and proportional width constraints on two "side spacer views" or, to make it just a little more light-weight, use
ConstraintLayoutGuide
instead of a clear view.Edit - for a little more clarification...
First, I should have specified that by ConstraintLayoutGuide I was referring to
UILayoutGuide
- whoops :(The task you've outlined:
Could also be described as:
Auto-layout does not have a way to set the Leading anchor to a percentage of the superview's width.
So, traditionally, we used clear-background "spacer" views:
With iOS 9, Apple introduced
UILayoutGuide
(docs):These cannot be added in Storyboard / IB, but can be used in code in much the same way as a standard
UIView
.Here's a simple example that adds a "cyan" view and a
UILayoutGuide
to a "container" view, providing 15% of "leading space" to the cyan view:The result - 15-pts (15%) for a 100-pt "container" view (red outline):
and, if we change the container width to 200-pts, we get 30-pts (15%) of leading space: