代码之家  ›  专栏  ›  技术社区  ›  jdanthinne

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

  •  2
  • jdanthinne  · 技术社区  · 7 年前

    我目前正在使用UICollectionView构建一个通用表单生成器。

    每个表单元素都是一个单元格,对于复选框,我使用单元格内的UIStackView来显示所有可用选项。

    问题是,每次我重用单元格时,即使我删除了所有arrangedSubviews,它们也会保留在新的视图中。

    以下代码是我正在执行的操作的简化版本:

    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) })
        }
    
    }
    

    相反,我目前的解决方法是在prepareforuse()中隐藏()每个arrangedSubview,而不是删除它们,但我不喜欢这样。

    2 回复  |  直到 7 年前
        1
  •  7
  •   Duncan C    4 年前

    如果您阅读 removeArrangedSubview 方法,他们说:

    讨论:此方法从堆栈中删除提供的视图 arrangedSubviews数组。视图位置和大小将不再为 由堆栈视图管理。但是,此方法不会删除 从堆栈的子视图数组中提供视图;因此,观点是 仍显示为视图层次的一部分。

    防止调用堆栈后视图出现在屏幕上 removeArrangedSubview:方法,显式地从 通过调用views removeFromSuperview()方法调用子视图数组,或 将视图的isHidden属性设置为true。

    因此,还需要从堆栈视图中删除子视图。(当我第一次开始使用堆栈视图时,我也很难做到这一点。)

    编辑:

    事实上,正如@kid\u x所指出的,只需使用 removeFromSuperView() 作品我不知道这有什么意义 removeArrangedSubview() 是,待定。


    编辑#2:

    我建议不要使用 removeArrangedSubview() 完全相反,请执行以下操作之一:

    选项1 : 如果需要从堆栈视图中永久删除视图,只需使用 removeFromSuperView() .

    选项2 : 如果要从堆栈视图中删除视图,然后再将其放回,只需切换子视图的isHidden属性,如上文的回答所述。堆栈视图将关闭空白空间,并重新定位其余视图,就像删除了它们一样。

        2
  •  2
  •   superandrew    5 年前

    在许多情况下,由于在可重用视图中从superview中删除可能(而且大多数情况下会)导致视图被释放,在UIStackView中

    dynamicView.isHidden = false
    

    删除和

    dynamicView.isHidden = true
    

    若要再次添加,将导致堆栈视图重新排列其他排列的视图。