我正在更新一个带有AdBannerView的旧应用程序,当没有广告时,它就会滑出屏幕。当有广告时,它就会在屏幕上滑动。基本的东西。
旧的风格,我设置帧在一个动画块。
新样式,我有一个IBOutlet到自动布局约束,它决定了Y的位置,在这种情况下,它是从父视图底部的距离,并修改常数:
- (void)moveBannerOffScreen {
[UIView animateWithDuration:5 animations:^{
_addBannerDistanceFromBottomConstraint.constant = -32;
}];
bannerIsVisible = FALSE;
}
- (void)moveBannerOnScreen {
[UIView animateWithDuration:5 animations:^{
_addBannerDistanceFromBottomConstraint.constant = 0;
}];
bannerIsVisible = TRUE;
}
横幅的移动和预期的完全一样,但是没有动画。
更新:我重新看了WWDC 12演讲《掌握自动布局的最佳实践》,其中包括动画。它讨论了如何使用CoreAnimation更新约束:
我尝试了下面的代码,但得到完全相同的结果:
- (void)moveBannerOffScreen {
_addBannerDistanceFromBottomConstraint.constant = -32;
[UIView animateWithDuration:2 animations:^{
[self.view setNeedsLayout];
}];
bannerIsVisible = FALSE;
}
- (void)moveBannerOnScreen {
_addBannerDistanceFromBottomConstraint.constant = 0;
[UIView animateWithDuration:2 animations:^{
[self.view setNeedsLayout];
}];
bannerIsVisible = TRUE;
}
另一方面,我已经检查了很多次,这是在主线程上执行的。
我很感激你提供的答案,但我认为最好能进一步讨论这个问题。
文档中的基本块动画
[containerView layoutIfNeeded]; // Ensures that all pending layout operations have been completed
[UIView animateWithDuration:1.0 animations:^{
// Make all constraint changes here
[containerView layoutIfNeeded]; // Forces the layout of the subtree animation block and then captures all of the frame changes
}];
但实际上,这是一个非常简单的场景。如果我想通过updateConstraints方法动画子视图约束?
调用子视图updateConstraints方法的动画块
[self.view layoutIfNeeded];
[self.subView setNeedsUpdateConstraints];
[self.subView updateConstraintsIfNeeded];
[UIView animateWithDuration:1.0f delay:0.0f options:UIViewAnimationOptionLayoutSubviews animations:^{
[self.view layoutIfNeeded];
} completion:nil];
updateConstraints方法在UIView子类中被重写,必须在方法的末尾调用super。
- (void)updateConstraints
{
// Update some constraints
[super updateConstraints];
}
自动布局指南有很多不足之处,但值得一读。我自己使用它作为UISwitch的一部分,它使用一个简单而微妙的折叠动画(0.2秒长)来切换带有一对UITextFields的子视图。子视图的约束被处理在UIView子类updateConstraints方法如上所述。
通常,你只需要更新约束并在动画块中调用layoutIfNeeded。这可以是改变NSLayoutConstraint的.constant属性,添加remove约束(iOS 7),或者改变约束的.active属性(iOS 8和9)。
示例代码:
[UIView animateWithDuration:0.3 animations:^{
// Move to right
self.leadingConstraint.active = false;
self.trailingConstraint.active = true;
// Move to bottom
self.topConstraint.active = false;
self.bottomConstraint.active = true;
// Make the animation happen
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
示例设置:
争议
有一些关于约束是否应该在动画块之前或里面改变的问题(见以前的答案)。
以下是教授iOS的马丁·皮尔金顿(Martin Pilkington)和自动布局(Auto Layout)作者肯·费里(Ken Ferry)在Twitter上的对话。Ken解释说,虽然在动画块之外改变常量目前可能工作,但这是不安全的,它们应该在动画块内部改变。
https://twitter.com/kongtomorrow/status/440627401018466305
动画:
示例项目
下面是一个简单的项目,展示了视图如何被动画化。它使用Objective C并通过改变几个约束的.active属性来动画视图。
https://github.com/shepting/SampleAutoLayoutAnimation