Reputation: 151166
When a view is animated by a gesture recognizer of tapping the main view:
-(void) doAnimate {
[UIView animateWithDuration:3
animations:^{
self.circleView.center = CGPointMake(100, 300);
}
completion:^(BOOL finished) {
NSLog(@"finished is %i", finished);
[UIView animateWithDuration:1 animations:^{
self.circleView.center = CGPointMake(250, 300);
}];
}
];
}
(there is chained animation). If it is animating and the main view is tapped again, I actually see the completion handler called twice, first with TRUE, and the second time with FALSE. I thought it was to be called only once, with FALSE? I can't find it in Apple's doc. Is there a rule for how it works if animation starts when it is already animating? (I think it apply it is the same view being animated again, and doesn't apply if view2 is animated while view1 is animating?)
Update: the following code can show more insight:
-(void) dropAnimate:(UIGestureRecognizer *) g {
int n = arc4random() % 10000;
int y = 501 + arc4random() % 200;
NSLog(@"y is %i", y);
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(100, y, 10, 10)];
label.text = @"x";
[self.view addSubview:label];
[UIView animateWithDuration:3
animations:^{
NSLog(@"n is %i", n);
self.circleView.center = CGPointMake(100, y);
}
completion:^(BOOL finished) {
NSLog(@"n is %i", n);
NSLog(@"finished is %i y is %i", finished, y);
[UIView animateWithDuration:3 animations:^{
self.circleView.center = CGPointMake(250, y);
}
];
}
];
NSLog(@"finished the method call");
}
In addition to @Kai's answer below, it seems that there is a rule to new animation for the same UIView object when there is already an animation going on: the old animation will finish its effect immediately, and the new animation is run, but then next the old animation's completion
is called with NO
, and now a 3rd animation is started, which causes animation 2 to finish the effect, but next its completion
block is called, with a NO
, and it causes animation 3 to take effect immediately... and we see animation 4 running for 3 seconds.
The above sample code can be tried... and to simplify it, just remove the completion
block, and then try it, and it confirms to the rule that says: if we start a new animation on the same object, the old animation takes effect immediately, and the new animation is run...
And with the completion
block, it can get quite complicated if the completion
block starts yet another animation...
So I think a finally thing is: does any docs or spec specify this behavior?
Upvotes: 4
Views: 1563
Reputation: 10775
I think what happens is the following:
Your first trigger sets the center
to (100,300)
and than animates the view (note that the center property
changes before you actually see it!). Your second trigger returns immediately (calls completion
with YES
), because there is nothing to animate (the property's already been set to the very same value before) and resets the center
and by that forces the first animation (still running) to stop with NO, because the circleview
is teared out from it's disired animation by getting a new center
(note that the 2nd trigger does not disturb the 1st animation before calling completion
, because the circleview
's center property
is not changed).
Upvotes: 1