Ios 使用AutoLayout设置视图的动画,但它会更改,而不会实际设置动画
我有一个自定义视图子类,为了清晰起见,我将提供它的所有代码。我强调了以下相关部分 注意:我知道如何使用AutoLayout设置视图动画。问题不在于编写动画代码。问题是它会更新视图,但实际上不会设置任何动画。它只是跳到了新的尺寸Ios 使用AutoLayout设置视图的动画,但它会更改,而不会实际设置动画,ios,swift,uiviewanimation,Ios,Swift,Uiviewanimation,我有一个自定义视图子类,为了清晰起见,我将提供它的所有代码。我强调了以下相关部分 注意:我知道如何使用AutoLayout设置视图动画。问题不在于编写动画代码。问题是它会更新视图,但实际上不会设置任何动画。它只是跳到了新的尺寸 class ExpandingButtonView: UIView { let titleLabel: UILabel = { let l = UILabel() l.translatesAutoresizingMaskIntoCo
class ExpandingButtonView: UIView {
let titleLabel: UILabel = {
let l = UILabel()
l.translatesAutoresizingMaskIntoConstraints = false
l.textColor = .white
l.setContentCompressionResistancePriority(UILayoutPriorityRequired, for: .vertical)
l.setContentHuggingPriority(UILayoutPriorityRequired, for: .vertical)
return l
}()
let buttonStack: UIStackView = {
let s = UIStackView()
s.translatesAutoresizingMaskIntoConstraints = false
s.axis = .vertical
s.spacing = 8
s.isLayoutMarginsRelativeArrangement = true
s.layoutMargins = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
return s
}()
var collapsed: Bool = true {
didSet {
animatedCollapsedState()
}
}
lazy var collapsedConstraint: NSLayoutConstraint = {
return self.bottomAnchor.constraint(equalTo: self.titleLabel.bottomAnchor, constant: 10)
}()
lazy var expandedConstraint: NSLayoutConstraint = {
return self.bottomAnchor.constraint(equalTo: self.buttonStack.bottomAnchor)
}()
init(title: String, color: UIColor, buttonTitles: [String]) {
super.init(frame: .zero)
translatesAutoresizingMaskIntoConstraints = false
layer.cornerRadius = 8
clipsToBounds = true
backgroundColor = color
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(toggleCollapsed))
tapGestureRecognizer.numberOfTapsRequired = 1
tapGestureRecognizer.numberOfTouchesRequired = 1
addGestureRecognizer(tapGestureRecognizer)
titleLabel.text = title
addSubview(titleLabel)
addSubview(buttonStack)
buttonTitles.forEach {
let button = UIButton(type: .system)
button.translatesAutoresizingMaskIntoConstraints = false
button.backgroundColor = UIColor(white: 1.0, alpha: 0.5)
button.setTitle($0, for: .normal)
button.tintColor = .white
button.layer.cornerRadius = 4
button.clipsToBounds = true
button.titleLabel?.font = .boldSystemFont(ofSize: 17)
button.setContentCompressionResistancePriority(UILayoutPriorityRequired, for: .vertical)
buttonStack.addArrangedSubview(button)
}
NSLayoutConstraint.activate([
collapsedConstraint,
titleLabel.topAnchor.constraint(equalTo: topAnchor, constant: 10),
titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10),
titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: 10),
titleLabel.bottomAnchor.constraint(equalTo: buttonStack.topAnchor),
buttonStack.leadingAnchor.constraint(equalTo: leadingAnchor),
buttonStack.trailingAnchor.constraint(equalTo: trailingAnchor),
])
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func toggleCollapsed() {
collapsed = !collapsed
}
func animatedCollapsedState() {
UIView.animate(withDuration: 1) {
self.collapsedConstraint.isActive = self.collapsed
self.expandedConstraint.isActive = !self.collapsed
self.layoutIfNeeded()
}
}
}
它有两种状态
崩溃了。。。
扩大。。。
当您点击它时,TapGestureRecognitor将切换折叠的值,从而触发didSet,然后设置UI动画
动画功能是
func animatedCollapsedState() {
UIView.animate(withDuration: 1) {
self.collapsedConstraint.isActive = self.collapsed
self.expandedConstraint.isActive = !self.collapsed
self.layoutIfNeeded()
}
}
然而。。。它不是动画。它只是跳转到新的大小,而没有实际设置动画
我已经删除了这个问题的另一部分观点。还有一个背景图像视图,在UI更改期间淡入/淡出。那确实很有生气。所以我不太确定这里发生了什么
我还尝试将约束更新移出动画块,并尝试在更新之前运行layoutIfNeeded
在所有情况下,它都会跳转到新的大小。您必须在视图的superview上调用LayoutIfNeed
class ExpandingButtonView: UIView {
let titleLabel: UILabel = {
let l = UILabel()
l.translatesAutoresizingMaskIntoConstraints = false
l.textColor = .white
l.setContentCompressionResistancePriority(UILayoutPriorityRequired, for: .vertical)
l.setContentHuggingPriority(UILayoutPriorityRequired, for: .vertical)
return l
}()
let buttonStack: UIStackView = {
let s = UIStackView()
s.translatesAutoresizingMaskIntoConstraints = false
s.axis = .vertical
s.spacing = 8
s.isLayoutMarginsRelativeArrangement = true
s.layoutMargins = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
return s
}()
var collapsed: Bool = true {
didSet {
animatedCollapsedState()
}
}
lazy var collapsedConstraint: NSLayoutConstraint = {
return self.bottomAnchor.constraint(equalTo: self.titleLabel.bottomAnchor, constant: 10)
}()
lazy var expandedConstraint: NSLayoutConstraint = {
return self.bottomAnchor.constraint(equalTo: self.buttonStack.bottomAnchor)
}()
init(title: String, color: UIColor, buttonTitles: [String]) {
super.init(frame: .zero)
translatesAutoresizingMaskIntoConstraints = false
layer.cornerRadius = 8
clipsToBounds = true
backgroundColor = color
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(toggleCollapsed))
tapGestureRecognizer.numberOfTapsRequired = 1
tapGestureRecognizer.numberOfTouchesRequired = 1
addGestureRecognizer(tapGestureRecognizer)
titleLabel.text = title
addSubview(titleLabel)
addSubview(buttonStack)
buttonTitles.forEach {
let button = UIButton(type: .system)
button.translatesAutoresizingMaskIntoConstraints = false
button.backgroundColor = UIColor(white: 1.0, alpha: 0.5)
button.setTitle($0, for: .normal)
button.tintColor = .white
button.layer.cornerRadius = 4
button.clipsToBounds = true
button.titleLabel?.font = .boldSystemFont(ofSize: 17)
button.setContentCompressionResistancePriority(UILayoutPriorityRequired, for: .vertical)
buttonStack.addArrangedSubview(button)
}
NSLayoutConstraint.activate([
collapsedConstraint,
titleLabel.topAnchor.constraint(equalTo: topAnchor, constant: 10),
titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10),
titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: 10),
titleLabel.bottomAnchor.constraint(equalTo: buttonStack.topAnchor),
buttonStack.leadingAnchor.constraint(equalTo: leadingAnchor),
buttonStack.trailingAnchor.constraint(equalTo: trailingAnchor),
])
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func toggleCollapsed() {
collapsed = !collapsed
}
func animatedCollapsedState() {
UIView.animate(withDuration: 1) {
self.collapsedConstraint.isActive = self.collapsed
self.expandedConstraint.isActive = !self.collapsed
self.layoutIfNeeded()
}
}
}
func animatedCollapsedState() {
self.collapsedConstraint.isActive = self.collapsed
self.expandedConstraint.isActive = !self.collapsed
UIView.animate(withDuration: 1) {
self.superview?.layoutIfNeeded()
}
}
隐马尔可夫模型。。。好的,现在正在动画制作中,谢谢,但是到处跳。我真的被这件事难住了。视图似乎在不改变大小的情况下跳转到最终位置,然后设置其大小的动画。好的。。。这很奇怪。我必须自己做。superview?.superview?.LayoutifNeed这很糟糕:我想我必须探索一种新的方法来做这件事。不过,它现在起作用了。谢谢:我刚开始制作一个视频来证明它是有效的很高兴我能帮忙!