如果删除和添加相同的视图,UIStackView 不会填充

UIStackView doesn't fill if removing and adding the same views

我在 iOS 9 中发现了一个问题,即在向 UIStackView 删除和添加相同的视图时布局无法正常工作,并且使用视图的固有内容大小而不是指定的 fillEqually分布类型。

例如,这段代码:

class ViewController: UIViewController {

    let stackView = UIStackView()

    let red = UIButton()
    let blue = UIButton()
    let green = UIButton()

    override func viewDidLoad() {
        super.viewDidLoad()

        stackView.distribution = .fillEqually

        red.backgroundColor = .red
        blue.backgroundColor = .blue
        green.backgroundColor = .green

        let views = [red, blue, green]

        for view in views {
            stackView.addArrangedSubview(view)
        }

        view.backgroundColor = .lightGray
        view.addSubview(stackView)
        stackView.frame = view.bounds.insetBy(dx: 0, dy: view.frame.height / 3)

        let button = UIButton()
        button.frame = view.bounds
        view.addSubview(button)

        button.addTarget(self, action: #selector(buttonClicked), for: .touchUpInside)
    }

    func buttonClicked() {
        for view in stackView.arrangedSubviews {
            view.removeFromSuperview()
        }

        stackView.addArrangedSubview(red)
        stackView.addArrangedSubview(blue)
    }
}

点击屏幕后显示以下结果:

但是在 iOS 10 它显示了预期的结果:

创建新视图而不是重复使用旧视图会在 iOS 9:

上输出预期的布局
func buttonClicked() {
    for view in stackView.arrangedSubviews {
        view.removeFromSuperview()
    }

    let red = UIButton()
    let blue = UIButton()
    red.backgroundColor = .red
    blue.backgroundColor = .blue

    stackView.addArrangedSubview(red)
    stackView.addArrangedSubview(blue)
}

但是这段代码的重点是重用视图来提高性能。

这是我的代码中的问题吗? iOS 9 上的错误?有任何已知的解决方法吗?

for view in stackView.arrangedSubviews {
    stackView.removeArrangedSubview(view)
    view.removeFromSuperview()
}

我想你忘了打电话给 removeArrangedSubview

通过在删除所有视图后显式调用 layoutIfNeeded 方法解决了这个问题:

func buttonClicked() {
    for view in stackView.arrangedSubviews {
        view.removeFromSuperview()
    }

    stackView.layoutIfNeeded()  // Required to avoid layout issues in iOS 9

    stackView.addArrangedSubview(red)
    stackView.addArrangedSubview(blue)
}