gpt4 book ai didi

ios - 使用 AutoLayout 为 View 设置动画,但它会在没有实际设置动画的情况下发生变化

转载 作者:行者123 更新时间:2023-11-28 14:57:23 25 4
gpt4 key购买 nike

我有一个自定义 View 子类,为了清楚起见,我将提供所有代码。我在下面突出显示了相关部分。

注意:我知道如何使用 AutoLayout 为 View 设置动画。问题不在于编写动画代码。问题是它更新了 View ,但实际上并没有为任何东西设置动画。它只是跳到新的大小。

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()
}
}
}

它有两个状态...

  1. 崩溃了...

enter image description here

  1. 扩展...

enter image description here

当您点击它时,tapGestureRecognizer 会切换 collapsed 值,该值会触发 didSet,然后为 UI 设置动画。

动画函数是...

func animatedCollapsedState() {
UIView.animate(withDuration: 1) {
self.collapsedConstraint.isActive = self.collapsed
self.expandedConstraint.isActive = !self.collapsed
self.layoutIfNeeded()
}
}

但是...它不是动画。它只是跳到新的大小而没有实际动画。

我已经删除了问题 View 的另一部分。还有一个在 UI 更改期间淡入/淡出的背景 ImageView 。这确实动画。所以我不太确定这里发生了什么?

我还尝试将约束更新移出动画 block ,并尝试在更新它们之前运行 layoutIfNeeded()

在所有情况下,它都会执行相同的操作以跳转到新尺寸。

最佳答案

您必须在 View 的父 View 上调用 layoutIfNeeded()

func animatedCollapsedState() {
self.collapsedConstraint.isActive = self.collapsed
self.expandedConstraint.isActive = !self.collapsed
UIView.animate(withDuration: 1) {
self.superview?.layoutIfNeeded()
}
}

关于ios - 使用 AutoLayout 为 View 设置动画,但它会在没有实际设置动画的情况下发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49198842/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com