xcode - 当 isHidden == true 时 UIStackView 从左侧动画
问题描述
我有一个 UIStackView 和一堆排列的子视图。我希望它们都隐藏在 viewDidLoad 所以我去做
public func setStackViewHidden(_ isHidden: Bool, animated: Bool) {
stackView.arrangedSubviews.forEach ({ subview in
if animated {
UIView.animate(withDuration: 0.3) {
subview.isHidden = isHidden
}
} else {
subview.isHidden = isHidden
}
})
}
这使得整个 stackView 隐藏起来。然后当我去使用与 isHidden == false 相同的方法时。它从左侧开始动画并向右扩展至正确的大小。为什么它不是从正确的宽度到底部的动画,而是从左边到整个尺寸?
解决方案
显示/隐藏排列的子视图时使用的内置动画UIStackView
可以很好地工作 --- 它可能不太好。
堆栈视图所做的关键事情之一是安排其子视图。当然,也经常使用子视图的宽度和高度来确定堆栈视图的宽度和高度。所以我们可以得到未定义的状态,并且动画——正如你所看到的——变得“不稳定”。
试一试(所有代码,没有@IBOutlets
or @IBActions
,所以只需为这个类分配一个视图控制器):
class StackShowHideViewController: UIViewController {
// UIButton
let btn: UIButton = {
let v = UIButton()
v.translatesAutoresizingMaskIntoConstraints = false
v.setTitle("Tap Me", for: .normal)
v.backgroundColor = .red
return v
}()
// vertical UIStackView
let stackView: UIStackView = {
let v = UIStackView()
v.translatesAutoresizingMaskIntoConstraints = false
v.axis = .vertical
v.alignment = .fill
v.distribution = .fill
v.spacing = 8
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
// add elements to view
view.addSubview(btn)
view.addSubview(stackView)
NSLayoutConstraint.activate([
// constrain button 20-pts from top, centered horizontally
btn.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20.0),
btn.centerXAnchor.constraint(equalTo: view.centerXAnchor),
// constrain stack view 20-pts from bottom of button
// centered horizontally
// width constrained to 160-pts
stackView.topAnchor.constraint(equalTo: btn.bottomAnchor, constant: 20.0),
stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
stackView.widthAnchor.constraint(equalToConstant: 160.0),
])
// add 5 UILabels to the stack view
for i in 1...5 {
let v = UILabel()
v.backgroundColor = .yellow
v.text = "This is Label \(i)"
v.textAlignment = .center
v.translatesAutoresizingMaskIntoConstraints = false
// inititially hidden
v.isHidden = true
// add label to stack view
stackView.addArrangedSubview(v)
// constrain label widths to width of stack view
v.widthAnchor.constraint(equalTo: stackView.widthAnchor).isActive = true
}
btn.addTarget(self, action: #selector(didTap(_:)), for: .touchUpInside)
}
public func setStackViewHidden(_ isHidden: Bool, animated: Bool) {
stackView.arrangedSubviews.forEach ({ subview in
if animated {
UIView.animate(withDuration: 0.3) {
subview.isHidden = isHidden
}
} else {
subview.isHidden = isHidden
}
})
}
@objc func didTap(_ sender: Any) {
// if labels are hidden, show them
// else, hide them
var h = true
if let v = stackView.arrangedSubviews.first {
h = v.isHidden
}
setStackViewHidden(!h, animated: true)
}
}
推荐阅读
- java - Java Pattern 匹配一个字符串,然后匹配任何字符,直到一个特定的字符
- python - 使用 Pandas 从另一列中查找满足某一列条件的值范围
- jquery - 如何使用 JQuery 将表 TR 元素与另一个 TR 切换
- python - 所有协变量的生命线危险比 = 1
- css - 移动 Chrome 上的 Web 响应问题
- android - Resources$NotFoundException 获取颜色 - Android Kotlin
- kubernetes - 当两个应用程序都使用相同的nodePort时,在kubernetes中部署应用程序的多个实例
- sql-server - 将oracle查询的日期格式转换为sql server查询
- jenkins - 如何通过詹金斯在电子邮件警报中发布断言失败
- css - 在 css-template 中使用“fr”符号在 Firefox 82.0 中不起作用