[英]How to use a variable UIStackView in UITableView or UICollectionView?
I'm currently building a generic form builder using a UICollectionView.我目前正在使用 UICollectionView 构建通用表单构建器。
Each form element is a cell, and for checkboxes, I'm using a UIStackView inside the cell to display all the available options.每个表单元素都是一个单元格,对于复选框,我在单元格内使用 UIStackView 来显示所有可用选项。
The problem is that each time I reuse the cell, even if I remove all the arrangedSubviews, they stay in the view with the new one.问题是,每次我重用单元格时,即使我删除了所有排列的子视图,它们也会与新视图一起留在视图中。
The following code is a simplified version of what I'm doing:以下代码是我正在做的事情的简化版本:
class cell: UICollectionViewCell {
@IBOutlet weak var stackView: UIStackView!
func setup(options: [String]) {
for option in options {
let label = UILabel()
label.text = option
stackView.addArrangedSubview(label)
}
}
override func prepareForReuse() {
super.prepareForReuse()
optionsStackView.arrangedSubviews.forEach({ optionsStackView.removeArrangedSubview(view: $0) })
}
}
Instead of that, my current workaround is to hide() each arrangedSubview in prepareForReuse() instead of removing them, but I don't like that.取而代之的是,我目前的解决方法是在 prepareForReuse() 中隐藏()每个排列的子视图,而不是删除它们,但我不喜欢那样。
If you read the Xcode docs on the removeArrangedSubview
method, they say:如果您阅读有关
removeArrangedSubview
方法的 Xcode 文档,他们会说:
Discussion: This method removes the provided view from the stack's arrangedSubviews array.
讨论:此方法从堆栈的排列子视图数组中删除提供的视图。 The view's position and size will no longer be managed by the stack view.
视图的位置和大小将不再由堆栈视图管理。 However, this method does not remove the provided view from the stack's subviews array;
但是,此方法不会从堆栈的 subviews 数组中删除提供的视图; therefore, the view is still displayed as part of the view hierarchy.
因此,视图仍然显示为视图层次结构的一部分。
To prevent the view from appearing on screen after calling the stack's removeArrangedSubview: method, explicitly remove the view from the subviews array by calling the view's removeFromSuperview() method, or set the view's isHidden property to true.
要防止在调用堆栈的 removeArrangedSubview: 方法后视图出现在屏幕上,请通过调用视图的 removeFromSuperview() 方法从子视图数组中显式删除视图,或将视图的 isHidden 属性设置为 true。
So you need to also remove the subviews from the stack view.因此,您还需要从堆栈视图中删除子视图。 (I also struggled with this when I first started using stack views.)
(当我第一次开始使用堆栈视图时,我也遇到了这个问题。)
In fact, as @kid_x points out, simply removing the subview with removeFromSuperView()
works.事实上,正如@kid_x 指出的那样,只需使用
removeFromSuperView()
删除子视图即可。 I'm not sure what the point of removeArrangedSubview()
is, TBH.我不确定
removeArrangedSubview()
是什么,TBH。
I would advise against using removeArrangedSubview()
at all.我建议不要使用
removeArrangedSubview()
。 Instead, do one of the following:相反,请执行以下操作之一:
Option 1 : If you need to remove a view from a stack view permanently, simply use removeFromSuperView()
.选项 1 :如果您需要从堆栈视图中永久删除视图,只需使用
removeFromSuperView()
。
Option 2 : If you want to remove views from your stack view and then put them back later, simply toggle the child view's isHidden property, as mentioned in suprandr's answer.选项 2 :如果您想从堆栈视图中删除视图,然后再将它们放回去,只需切换子视图的 isHidden 属性,如 suprandr 的回答中所述。 The stack view will close up the empty space and reposition the remaining views as if you removed them.
堆栈视图将关闭空白空间并重新定位剩余的视图,就像您删除它们一样。
In many cases, since removing from a superview in a reusable view could (and mostly, will) cause the view to be released, in a UIStackView simply putting在许多情况下,由于从可重用视图中的超视图中删除可能(并且大多数情况下会)导致视图被释放,因此在 UIStackView 中只需将
dynamicView.isHidden = false
to remove and删除和
dynamicView.isHidden = true
to add again, will cause the stack view to rearrange the other arranged views.再次添加,将导致堆栈视图重新排列其他排列的视图。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.