我有一些动画正在尝试转换为约束。其背后的想法是当出现错误时会弹出登录提示。
我的方法是视图控制器上的所有内容都在bounceView 中,它本身就在主视图中。
使用居中约束和前导空间约束将bounceView 绑定到主视图。为了在设计时使布局明确,还有一个前导空间和顶部空间约束。不过,这些只是占位符,在运行时会替换为相等的高度/宽度约束。
没有其他约束与主视图相关联。
现在,一些细节......</p>
我使用这些约束来定义反弹:
enum {animationDone, bounceStart, bounceLeft, bounceRight, bounceReturn};
static const NSTimeInterval BounceDuration = 20.0;
static const int NumberOfBounces = 3;
static const CGFloat BounceDistance = 16.0f;
(20 秒的延迟通常要短得多;我增加了延迟以证明这不起作用。)
额外的运行时约束设置如下:
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:_bounceView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:_bounceView attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0]];
}
我用这段代码开始动画:
_animateCount = NumberOfBounces;
_animateStage = bounceStart;
[self animationStep];
实际代码非常简单:
- (void)animationStep {
CGFloat bounceTo = 0;
BOOL half = NO;
switch (_animateStage) {
case bounceStart:
_animateStage = bounceLeft;
bounceTo = -BounceDistance;
half = YES;
break;
case bounceLeft:
_animateStage = bounceRight;
bounceTo = BounceDistance;
break;
case bounceRight:
if ( --_animateCount > 0 ) {
_animateStage = bounceLeft;
bounceTo = -BounceDistance;
} else {
_animateStage = bounceReturn;
bounceTo = 0;
}
break;
case bounceReturn:
half = YES;
_animateStage = animationDone;
break;
}
BOOL finishedAnimation = ( ( _animateStage == animationDone ) || ( self.view == nil ) );
if ( !finishedAnimation ) {
[_bounceView layoutIfNeeded];
_centerX.constant = bounceTo;
[_bounceView setNeedsUpdateConstraints];
NSTimeInterval duration = half ? BounceDuration / 2.0f : BounceDuration;
[UIView animateWithDuration:duration delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
NSLog(@"Bouncing to %f over %f seconds.", bounceTo, duration);
[_bounceView layoutIfNeeded];
} completion:^(BOOL finished) {
[self animationStep];
}];
}
}
然而,这一切都立即完成:
2013-10-29 10:59:43.852 App[9151:907] Bouncing to -16.000000 over 20.000000 seconds.
2013-10-29 10:59:43.864 App[9151:907] Bouncing to 16.000000 over 20.000000 seconds.
2013-10-29 10:59:43.865 App[9151:907] Bouncing to -16.000000 over 20.000000 seconds.
2013-10-29 10:59:43.866 App[9151:907] Bouncing to 16.000000 over 20.000000 seconds.
2013-10-29 10:59:43.866 App[9151:907] Bouncing to -16.000000 over 20.000000 seconds.
2013-10-29 10:59:43.867 App[9151:907] Bouncing to 16.000000 over 20.000000 seconds.
2013-10-29 10:59:43.867 App[9151:907] Bouncing to 0.000000 over 20.000000 seconds.
有任何想法吗?
更新
对于后人来说,这是由调用setNeedsUpdateConstraints
和layoutIfNeeded
子视图引起的。尽管 Apple 的文档另有说明,但您需要在 superview 上调用它。我在下面的答案中对此进行了详细说明。
但是,我已经接受了@nielsbot 的回答。尽管不是我问题的直接答案,但它比修复我试图做的事情更好。