动态 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: Fill
、Distribution: Fill Equally
和 Spacing: 8
接下来,select A 和刚刚创建的 StackView,并将 它们 嵌入到 Vertical StackView 中。还使用 Alignment: Fill
、Distribution: Fill Equally
和 Spacing: 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 的 子视图 。有意义吗?
我正在尝试使用 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: Fill
、Distribution: Fill Equally
和 Spacing: 8
接下来,select A 和刚刚创建的 StackView,并将 它们 嵌入到 Vertical StackView 中。还使用 Alignment: Fill
、Distribution: Fill Equally
和 Spacing: 8
现在,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 的 子视图 。有意义吗?