在 iOS 上更改隐藏的 属性 时,UIStackView 不会设置动画 9
UIStackView won't animate when changing the hidden property on iOS 9
我正在使用 Stack 视图创建一种 table UI,我在 StackView 中有 6 个视图,0、2、4 是可见的,1、3、5 是隐藏的。当点击其中一个可见视图时,我希望 "open" 隐藏的视图之一。
我的代码在 iOS 10 上运行良好,但由于某些原因我无法理解它在 iOS 9 上运行不佳。
请注意,如果我加载所有打开的视图,关闭动画将起作用,但将隐藏 属性 设置为 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
})
}
}
}
如果有人遇到这个问题。
我能够通过删除 -
来解决这个问题
stackView.distribution = .fillProportionally
我不确定为什么会这样,但我发现 Autolayout 添加了一个名为 'UISV-fill-proportionally' 的高度约束,其常量为 0,优先级高于我的高度约束。删除 fillProportionally 解决了这个问题。
- 保持视图的高度优先级低于 1000(为 999)。
- 如果已经隐藏就不要设置
setHidden:true
(这是UIStackView的bug)
我正在使用 Stack 视图创建一种 table UI,我在 StackView 中有 6 个视图,0、2、4 是可见的,1、3、5 是隐藏的。当点击其中一个可见视图时,我希望 "open" 隐藏的视图之一。
我的代码在 iOS 10 上运行良好,但由于某些原因我无法理解它在 iOS 9 上运行不佳。
请注意,如果我加载所有打开的视图,关闭动画将起作用,但将隐藏 属性 设置为 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
})
}
}
}
如果有人遇到这个问题。
我能够通过删除 -
来解决这个问题stackView.distribution = .fillProportionally
我不确定为什么会这样,但我发现 Autolayout 添加了一个名为 'UISV-fill-proportionally' 的高度约束,其常量为 0,优先级高于我的高度约束。删除 fillProportionally 解决了这个问题。
- 保持视图的高度优先级低于 1000(为 999)。
- 如果已经隐藏就不要设置
setHidden:true
(这是UIStackView的bug)