简体   繁体   English

如何在 UITableView 或 UICollectionView 中使用变量 UIStackView?

[英]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.) (当我第一次开始使用堆栈视图时,我也遇到了这个问题。)

Edit:编辑:

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。


Edit #2:编辑#2:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM