如何使用自动布局设置动画
如果没有自动布局,动画将随着时间的推移而改变视图的帧。使用自动布局时,约束条件决定了视图框架,因此你必须为约束设置动画。这种间接使动画更难以可视化。
以下是使用自动布局设置动画的方法:
- **** 使用定期调用(
CADisplayLink
,dispatch_source_t
,dispatch_after
,NSTimer
)创建后更改约束的常量。然后调用layoutIfNeeded
来更新约束。例:
Objective-C 的:
self.someConstraint.constant = 10.0;
[UIView animateWithDuration:0.25 animations:^{
[self.view layoutIfNeeded];
}];
迅速:
self.someConstraint.constant = 10.0
UIView.animate(withDuration: 0.25, animations: self.view.layoutIfNeeded)
- 更改约束并在动画块内调用
[view layoutIfNeeded]
。这会在动画期间忽略约束的两个位置之间进行插值。
[UIView animateWithDuration:0.5 animations:^{
[view layoutIfNeeded];
}]
-
更改约束的优先级。这比添加和删除约束的 CPU 密集度更低。
-
删除所有约束并使用自动调整遮罩。对于后者,你必须设置
view.translatesAutoresizingMaskIntoConstraints = YES
。 -
使用不会干扰预期动画的约束。
-
使用容器视图。使用约束定位超级视图。然后添加具有不与动画对抗的约束的子视图,例如:相对于超视图的中心。这会将部分约束卸载到 superview,因此它们不会在子视图中对抗动画。
-
动画图层而不是视图。图层变换不会触发自动布局。
CABasicAnimation* ba = [CABasicAnimation animationWithKeyPath:@"transform"];
ba.autoreverses = YES;
ba.duration = 0.3;
ba.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.1, 1.1, 1)];
[v.layer addAnimation:ba forKey:nil];
-
覆盖 layoutSubviews 。调用
[super layoutSubviews]
并微调约束。 -
在 viewDidLayoutSubviews 中更改框架。自动布局应用于
layoutSubviews
,因此一旦完成,请在viewDidLayoutSubviews
中进行更改。 -
选择自动布局并手动设置视图。你可以在不调用超类的实现的情况下覆盖
layoutSubviews
/layout
。
快速提示:如果没有插入动画视图的父级(即动画从开始到结束状态跳转),请在最深视图中调用 layoutIfNeeded()
,该视图是动画视图的父级(换句话说,即不受动画的影响)。我不知道为什么这个有效。