iOS 如何为自动版面设置动画

示例

如果没有“自动布局”,动画将随着时间的推移更改视图的帧而完成。使用“自动布局”时,约束决定了视图框架,因此您必须为约束设置动画。这种间接方式使动画更难以可视化。

以下是使用“自动版式”制作动画的方法:

  1. 改变约束的不断使用周期调用创建后(CADisplayLink,dispatch_source_t,dispatch_after,NSTimer)。然后调用layoutIfNeeded以更新约束。例:

目标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)

  1. 更改约束并[view layoutIfNeeded]在动画块内调用。这会在两个位置之间插值,而忽略了动画期间的约束。

[UIView animateWithDuration:0.5 animations:^{
    [view layoutIfNeeded];
}]

  1. 更改约束的优先级。与添加和删除约束相比,这占用的CPU更少。

  2. 删除所有约束并使用自动调整掩码。对于以后,您必须设置view.translatesAutoresizingMaskIntoConstraints = YES。

  3. 使用不会干扰预期动画的约束

  4. 使用容器视图。使用约束定位超级视图。然后添加一个子视图,该子视图的约束不会与动画发生冲突,例如:相对于父视图的中心。这会将部分约束卸载到父视图,因此它们不会与子视图中的动画作斗争。

  5. 设置图层动画代替视图。图层变换不会触发自动布局。

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];

  1. 覆盖layoutSubviews。调用[super layoutSubviews]并微调约束。

  2. 更改viewDidLayoutSubviews中的框架。自动版式已应用到中layoutSubviews,因此一旦完成,请在中进行更改viewDidLayoutSubviews。

  3. 退出自动版式并手动设置视图。您可以执行此覆盖layoutSubviews/layout而不调用超类的实现。

快速提示:如果未插入动画视图的父级(即动画从开始状态跳转到结束状态),请调用layoutIfNeeded()最深的视图,该视图是已动画视图的父级(换句话说,即不受动画影响)。我不知道为什么会这样。