在iOS 9上更改隐藏属性时,UIStackView不会动画

sha*_*oga 9 animation ios swift uistackview

我使用Stack视图来创建一种表UI,我在StackView中有6个视图0,2,4是可见的,1,3,5是隐藏的.当点击其中一个可见视图时,我希望"打开"其中一个隐藏的视图.

我有这个代码在iOS 10上运行良好,但由于某些原因我无法理解它在iOS 9上运行不佳.

请注意,如果我将视图全部打开,则关闭动画将起作用,但在将hidden属性设置为false时将无法打开.

这是我的代码 -

编辑 经过一些调试看起来视图高度约束也没有从隐藏中恢复,它的帧仍然是高度为0.

 import UIKit

class DeckView: UIView {

}

class ViewController: UIViewController {

var scrollView: UIScrollView!
var stackView: UIStackView!

override func viewDidLoad() {
    super.viewDidLoad()

    scrollView = UIScrollView()
    scrollView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(scrollView)

    view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[scrollView]|", options: .alignAllCenterX, metrics: nil, views: ["scrollView": scrollView]))
    view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[scrollView]|", options: .alignAllCenterX, metrics: nil, views: ["scrollView": scrollView]))


    stackView = UIStackView()
    stackView.translatesAutoresizingMaskIntoConstraints = false
    stackView.spacing = 0
    stackView.alignment = .center
    stackView.distribution = .fillProportionally
    stackView.axis = .vertical
    scrollView.addSubview(stackView)

    scrollView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[stackView]|", options: NSLayoutFormatOptions.alignAllCenterX, metrics: nil, views: ["stackView": stackView]))
    scrollView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[stackView]|", options: NSLayoutFormatOptions.alignAllCenterX, metrics: nil, views: ["stackView": stackView]))


    for i in 0 ..< 8 {
        let view  = DeckView()
        view.tag = i
        view.translatesAutoresizingMaskIntoConstraints = false
        view.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width).isActive = true
        view.isUserInteractionEnabled = true

        if i%2 == 0 {
            view.backgroundColor   = UIColor.magenta
            let constriant = view.heightAnchor.constraint(equalToConstant:160)
            constriant.priority = 999
            view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.openDeck(_:))))
            view.addConstraint(constriant)

        } else {
            view.backgroundColor   = UIColor.red
            let constriant = view.heightAnchor.constraint(equalToConstant:160)
            constriant.priority = 999
            view.addConstraint(constriant)
            view.isHidden = false
        }

        stackView.addArrangedSubview(view)
    }
}

func openDeck(_ sender:UIGestureRecognizer) {
    if let view = sender.view as? DeckView,
    let childView = stackView.viewWithTag(view.tag + 1) {
            UIView.animate(withDuration: 0.4, animations: {
                childView.isHidden = !childView.isHidden
            })
    }
}
}
Run Code Online (Sandbox Code Playgroud)

小智 41

  1. 保持视图的高度优先级低于1000(转到999).
  2. 不要设置setHidden:true它是否已被隐藏(这是UIStackView的错误)

  • 我不能为此感谢你.2015年的**问题**(雷达[UIStackView:用动画隐藏的切换卡在隐藏模式中](http://www.openradar.me/22819594)和[在UIStackView的子视图上调用setHidden:NO不会总是显示它](http://www.openradar.me/25087688)@blackjacx的要求)和**步骤2中的**解决方案**仍然在2017年8月有效.我应该提到我不需要携带第1步(和`distribution = .fill`对我来说没问题).这个错误显然与动画有关,因为当我立即切换"isHidden"时它没有浮出水面. (6认同)
  • 这在 iOS 13 中仍然存在 -_____________________-' (3认同)
  • [本文](https://useyourloaf.com/blog/stack-view-constraint-conflicts-when-hide-views/)和[本文](http://angelolloqui.com/blog/36-Oddities- -UIStackView)在桶的步骤1的推理背后有很好的解释。总结:*“基本上,这里发生的是垂直堆栈视图会自动将视图的高度设置为0 px以隐藏它。但是,如果存在冲突诸如填充之类的约束可能会尝试使其保持较高的高度(例如16像素),那么您将需要降低这些约束的优先级,以便在隐藏时将其缩短到0像素的高度。“ * (2认同)

sha*_*oga 2

如果有人偶然发现这个问题。

我能够通过删除-来解决这个问题

stackView.distribution = .fillProportionally
Run Code Online (Sandbox Code Playgroud)

我不确定为什么会发生这种情况,但我发现自动布局添加了一个名为“UISV-fill-proportionalally”的高度约束,其常量为 0,并且优先级高于我的高度约束。删除 fillProportional 解决了该问题。