UIStackView - 从中​​心均匀分布视图

UIStackView - Distribute views evenly from the centre

我有一个 UIStackView,里面有一个 UIScrollView 来显示水平排列的动态添加的子视图。当前的解决方案将从左侧开始显示项目,我想在不改变子视图的宽度和高度的情况下从中心开始分配项目。我怎么做?我也对不使用 UIStackView 的解决方案持开放态度。这样我就可以支持设备 < iOS9.

(当前)

(预期)

简答:

ScrollView 约束

Leading >= 0, Trailing >= 0, Top >= 0, Bottom >= 0
Center X  and Center Y 

StackView 约束

Leading = 0, Trailing = 0, Top = 0, Bottom = 0
StackView width = ScrollView width (priority low :250)
StackView height = ScrollView height

长答案

首先,你的结构很好,我们有:

UIScrollView
     UIStackView (horizontal)
         Subviews 

所以,为了达到目标我们应该:

  • 居中 UIScrollView
  • 设置 UIScrollView 的 contentSize 等于内在内容 UIStackView
  • 的大小

操作方法如下:

第 1 步:使 UIScrollView 的框架居中

CenterYCenterX 约束用于使 UIScrollView

的框架居中

Leading Space >= 0, Trailling Space >= 0, Top Space >= 0, Bottom Space >= 0用于防止UIScrollView的frame超出父视图的框架

我使用占位符固有大小不显示与 UIScrollView 的 contentSize 相关的错误(因为我们还没有子视图,所以 contentSize)。

现在,我们UIScrollView的框架就OK了,进入下一步:)

第2步:添加横向UIStackView

  • 顶部、底部、前导、尾随约束用于修复 UIStackView 框架
  • 用于计算等高和等宽 UIScrollView 的内容大小

PS。 UIStackView frame 的任何变化,都会改变 UIScrollView 的 contentSize

第 3 步:添加子视图

因为我们在UIStackView中使用了Fill Distribution所有subviews必须有一个内在的内容大小(或高度和宽度限制(不是首选))。 例如,如果我们使用 Fill Equally,只有一个 subview 具有固有内容大小(或高度和宽度限制(不是首选))就足够了,其他子视图大小将等于这个。

例如:我将添加 3 个标签(请删除 UIScrollView 的占位符固有大小)

有效!!不,不,还没有尝试添加第四个和五个标签:)

为什么?

为了理解,我们将通过两个示例计算视图的每个元素的框架:

父视图大小:200、200 第一个标签固有内容大小:120、50 第二个标签固有内容大小:150、50

第一个例子(只有第一个标签在UIStackView

  • UIStackView 内在内容大小 = 120, 50
  • UIScrollView contentSize = 120, 50
  • UIScrollView 帧数 = 40, 75, 120, 50

所有帧都OK

第二个例子(有两个标签)

  • UIScrollView 帧 = 0, 0, 200, 50
  • UIScrollView contentSize = 200, 50
  • UIStackView 内在内容大小 = 200, 50

因此,UIStackView 无法正确显示两个标签(因为 UIStackView 的宽度小于两个标签的宽度),我们没有滚动条,因为, UIStackView 约束宽度等于 UIScrollView 的宽度。 它在 UIStackView 内在内容大小小于最大 UIScrollView 帧时起作用。

为了解决这个问题,我们将宽度约束的优先级更改为低于 UIStackView 内在内容大小优先级值的值,并且一切正常:)

希望对您有所帮助。

Code source