我正在尝试使用UIStackView
构建一个堆栈视图,该视图总是在最多时显示3个视图,但也可以同时显示无,1或2个视图。
整个堆栈视图应该是动态的。一开始堆栈视图为空。另一个函数将在顶部添加stackView.insertArrangedSubview(at: 0)
的新视图。如果添加了另一个视图,则应将索引0处的上一个视图推送到索引1.这就是我选择UIStackView
的原因,因为它负责重新排序现有视图。
当推入第三个视图时,另外两个视图将再次向下移动一个插槽。现在,如果第四个视图被推入,所有前三个视图将再次向下移动,但第四个视图将从堆栈视图中删除。
虽然这里有一个额外的条件:
第一个索引处的视图应始终是其余2个视图的两倍。因此,第一个视图应该是整个堆栈视图的50%。因此,指数1和2的观点应该是25%的高度。
如果推入新视图,则当前在索引0视图将不得不缩小,向下移动到中间,并移动到堆栈视图的索引1。
这个想法类似于Growl Notification System的工作原理。
此image显示了视图外观的基本布局。
现在的问题是,UIStackView
是解决此问题的正确方法,还是只使用约束(例如使用SnapKit
)是更好的方法?即使使用UIStackView
,我也可能需要有很多限制才能满足要求。
所以也许我应该只有一个addNewView
函数来更新所有约束并在layoutIfNeeded
块中调用UIView.animate
以使视图的转换按下其他约束和最后一个视图被赶出去了?
你们觉得怎么样?如果存在已经做类似事情的框架,我也会很感激。
答案 0 :(得分:0)
这是一个选项。您需要一些代码来管理添加/删除视图,但这并不困难。注意遵循图像:
首先将View A,View B和View C放在主视图上。不要担心尺寸或定位,也不要给他们任何约束...... StackView将处理所有这些。
选择B和C并将它们嵌入垂直StackView中。 Alignment: Fill
,Distribution: Fill Equally
和Spacing: 8
接下来,选择A和刚刚创建的StackView,并将它们嵌入到Vertical StackView中。同时使用Alignment: Fill
,Distribution: Fill Equally
和Spacing: 8
现在,选择这个新创建的StackView - "最顶层" StackView - 并根据需要给它约束......在这里我设置前导,顶部,尾部和底部都等于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视图总会存在,因为你在这里看到它们(背景清晰,所以你不会真正看到它们)。当你添加/删除/移动"新"视图,您将它们添加为A,B和C的子视图。有意义吗?