如何使用自動佈局設定動畫
如果沒有自動佈局,動畫將隨著時間的推移而改變檢視的幀。使用自動佈局時,約束條件決定了檢視框架,因此你必須為約束設定動畫。這種間接使動畫更難以視覺化。
以下是使用自動佈局設定動畫的方法:
- **** 使用定期呼叫(
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()
,該檢視是動畫檢視的父級(換句話說,即不受動畫的影響)。我不知道為什麼這個有效。