假设我们希望将一个视图在某个时刻移出屏幕,这个视图的约束有一个负责决定 Y 坐标,它有一个 IBOutlet
,是距离父视图底部的距离,所以我们要修改它的 constant。
- (void)moveBannerOffScreen {
[UIView animateWithDuration:5
animations:^{
_addBannerDistanceFromBottomConstraint.constant = -32;
}];
bannerIsVisible = FALSE;
}
- (void)moveBannerOnScreen {
[UIView animateWithDuration:5
animations:^{
_addBannerDistanceFromBottomConstraint.constant = 0;
}];
bannerIsVisible = TRUE;
}
视图确实移动了,就像预期的那样,但是动画并没有发生。
所以如何让约束变动以动画形式呈现呢?
两个重点:
- 需要在动画 block 中调用
layoutIfNeeded
。苹果实际上建议在动画 block 之前调用一次,以确保所有待处理的布局操作都已完成 - 需要在父视图(例如 self.view)上调用它,而不是那个被附加约束的子视图。这么做会更新所有有约束的视图,也会让其它与这个被改变约束的视图有约束关系的视图产生动画。(例如视图 B 贴在 视图 A 的底部,如果你改变了视图 A 的顶部偏移量,你希望 B 也能有动画)
所以要这么做:
Objective-C
- (void)moveBannerOffScreen {
[self.view layoutIfNeeded];
_addBannerDistanceFromBottomConstraint.constant = -32;
[UIView animateWithDuration:5
animations:^{
[self.view layoutIfNeeded]; // Called on parent view
}];
bannerIsVisible = FALSE;
}
- (void)moveBannerOnScreen {
[self.view layoutIfNeeded];
_addBannerDistanceFromBottomConstraint.constant = 0;
[UIView animateWithDuration:5
animations:^{
[self.view layoutIfNeeded]; // Called on parent view
}];
bannerIsVisible = TRUE;
}
Swift 3
_addBannerDistanceFromBottomConstraint.constant = 0
UIView.animate(withDuration: 5) {
self.view.layoutIfNeeded()
}