Xcode 当isHidden==true时,从左侧设置动画的UIStackView
我有一个包含许多排列子视图的视图。我希望它们都隐藏在viewDidLoad上,所以我去做了Xcode 当isHidden==true时,从左侧设置动画的UIStackView,xcode,jquery-animate,uistackview,Xcode,Jquery Animate,Uistackview,我有一个包含许多排列子视图的视图。我希望它们都隐藏在viewDidLoad上,所以我去做了 public func setStackViewHidden(_ isHidden: Bool, animated: Bool) { stackView.arrangedSubviews.forEach ({ subview in if animated { UIView.animate(withDuration: 0.3) {
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
或@IBActions
,因此只需为此类分配一个视图控制器):
根据约束的设置方式,当所有视图都隐藏时,堆栈视图没有固有大小。因此,当子视图“取消隐藏”时,动画将在设置大小之前开始。尝试为第一个排列的子视图设置宽度约束,看看是否得到所需的结果。没有帮助,也许在我的stackview中覆盖intristicSize会有所帮助。
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)
}
}