如何为AutoLayout约束同时应用不同动画曲线?
给同一视图的不同约束应用不同动画并同时执行
嘿,这个场景我太熟了!之前我也纠结过怎么给同一个视图的不同约束组套不同的动画曲线还让它们同时跑,其实只要把动画拆成两个独立的块就行,核心思路是先把所有约束的变化都设置好,再分别触发不同的动画来驱动布局更新,下面给你两种实用的实现方式:
方法一:用UIView.animate多动画块实现
首先你得提前把要修改的约束通过IBOutlet连到代码里(比如宽、高、中心X/Y的约束),然后按下面的步骤操作:
- 先一次性设置好所有约束的目标值
// 假设你已经通过IBOutlet拿到这些约束的引用 viewWidthConstraint.constant = 200 viewHeightConstraint.constant = 200 viewCenterXConstraint.constant = 100 viewCenterYConstraint.constant = 100
- 分别启动线性动画和弹簧动画,记得加上
.beginFromCurrentState选项保证两个动画同时开始
// 线性动画:处理宽高约束的动画 UIView.animate(withDuration: 0.5, delay: 0, options: .beginFromCurrentState) { self.view.layoutIfNeeded() } // 弹簧动画:处理中心约束的动画 UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.5, options: .beginFromCurrentState) { self.view.layoutIfNeeded() }
方法二:用UIViewPropertyAnimator(更灵活可控)
如果需要更精细的动画控制(比如暂停、继续、调整进度),推荐用UIViewPropertyAnimator:
// 1. 创建两个不同的动画器,分别对应线性和弹簧曲线 let linearAnimator = UIViewPropertyAnimator(duration: 0.5, curve: .linear) { self.view.layoutIfNeeded() } let springAnimator = UIViewPropertyAnimator(duration: 0.5, dampingRatio: 0.7) { self.view.layoutIfNeeded() } // 2. 设置约束目标值 viewWidthConstraint.constant = 200 viewHeightConstraint.constant = 200 viewCenterXConstraint.constant = 100 viewCenterYConstraint.constant = 100 // 3. 同时启动两个动画 linearAnimator.startAnimation() springAnimator.startAnimation()
关键要点提醒
- 绝对不要在动画块里修改约束:一定要先把所有约束的目标值都设置好,再启动动画,这样系统才能正确计算布局变化
.beginFromCurrentState选项很重要:它能保证两个动画从当前布局状态同时开始,不会出现先后执行或者动画覆盖的问题layoutIfNeeded()要在每个动画块里调用:每个动画块都会触发布局更新,系统会自动区分不同约束对应的动画曲线
内容的提问来源于stack exchange,提问作者aunnnn
相关产品推荐
相关产品推荐

