动态 UIStackView 与普通约束

Dynamic UIStackView vs. plain constraints

我正在尝试使用 UIStackView 构建堆栈视图,它始终最多显示 3 个视图,但也可以同时显示 none、1 或 2 个视图。

整个堆栈视图应该是动态的。一开始堆栈视图是空的。另一个函数将在顶部添加一个新视图 stackView.insertArrangedSubview(at: 0)。如果添加另一个视图,则索引 0 处的前一个视图应被推送到索引 1。这就是我选择 UIStackView 的原因,因为它负责现有视图的重新排序。

当第三个视图被推入时,另外两个视图将再次向下移动一个插槽。现在,如果第四个视图被推入,所有之前的三个视图将再次向下移动,但第四个将从堆栈视图中删除。

这里有一个小的额外条件:

第一个索引处的视图应始终是其余 2 个视图的两倍大小。所以第一个视图应该占整个堆栈视图的 50%。因此,索引 1 和 2 处的视图高度应为 25%。

如果推入新视图,则当前位于索引 0 的视图将因此必须缩小,向下移动到中间,并移动到堆栈视图的索引 1。

这个想法类似于 Growl Notification System 的工作方式。

此 image 显示了视图的基本布局。

所以现在的问题是,UIStackView 是解决此问题的正确方法还是仅使用约束(例如使用 SnapKit)是更好的方法?即使 UIStackView 我可能需要有很多限制才能满足要求。

所以也许我应该有一个 addNewView 函数来更新所有约束并在 UIView.animate 块中调用 layoutIfNeeded 以使视图的过渡向下推其他视图和最后一个视图被推出?

大家怎么看?如果有一个框架已经做了类似的事情,我也将不胜感激。

这是一种选择。您需要一些代码来管理添加/删除视图,但这应该不难。注释如下图:

首先将视图 A、视图 B 和视图 C 放置到主视图上。不要担心大小或定位,也不要给它们任何限制……StackView 会处理所有这些。

Select B 和 C 并将它们嵌入到 Vertical StackView 中。 Alignment: FillDistribution: Fill EquallySpacing: 8

接下来,select A 和刚刚创建的 StackView,并将 它们 嵌入到 Vertical StackView 中。还使用 Alignment: FillDistribution: Fill EquallySpacing: 8

设置此 StackView

现在,select 这个新创建的 StackView - "top most" StackView - 并根据需要给它约束...这里我将 Leading、Top、Trailing 和 Bottom 都设置为 16。

现在,您只需要如下代码:

func addView(newView: UIView) -> Void {

    // if ViewC has a subview, remove its subview
    // if ViewB has a subview, move ViewB's subview to ViewC
    // if ViewA has a subview, move ViewA's subview to ViewB
    // add newView as a subview of ViewA

}

呃...试图在这一点上真正清楚...视图 A、B 和 C 将始终存在,就像您在此处看到的一样(具有清晰的背景,因此您不会真正看到它们)。当您添加/删除/移动 "new" 视图时,您将它们添加为 A、B 和 C 的 子视图 。有意义吗?