Reputation: 33138
-(void) movePinsToDestinations:(NSArray *)destination withCompletion: (void (^)())block
{
...
[UIView animateWithDuration:animationTime animations:^{
//[self.ReloadBut setTitle:@"Animating " forState:UIControlStateNormal];
for (BGAddressAnnotation * anExistingAnnotation in existingAnnotations) {
if (anExistingAnnotation.destination) {
anExistingAnnotation.coordinate = anExistingAnnotation.destination.coordinate;
}
else
{
anExistingAnnotation.myView.alpha = 0;
}
}
} completion:^(BOOL finished){
NSAssert(finished, @"Not Finished?");
for (BGAddressAnnotation * existingAnnotation in existingAnnotations) {
if ([existingAnnotation.destination.myBiz isEqual: existingAnnotation.myBiz]) {
existingAnnotation.arrayOfBusinesses = existingAnnotation.destination.arrayOfBusinesses;
existingAnnotation.myView.alpha=1;
}
else
{
[self.theMapView removeAnnotation:existingAnnotation];
}
}
// PO([[self class] PrintAllAnnotations: [self annotationExceptUser]]);
// PO([[self class] PrintAllAnnotations: destination]);
PO(@"Reach Completion Block");
if (block)
{
block();
}
else
{
//[self.ReloadBut setTitle:@"Animating Finish" forState:UIControlStateNormal];
}
}];
}
Result:
2012-11-04 20:00:05.800 @"Start Animating": Start Animating
2012-11-04 20:00:05.805 @"Reach Completion Block": Reach Completion Block
I set the animation to run for 10 seconds and yet completion block is called withhin 5 milisecond. What can possibly do this?
Some background, the function is called twice and the completion block is supposed to call another animation. The second animation is indeed done in 10 seconds. Does specifying completion block make it called immediately or what?
So I am effectively doing
[self movePinsToDestinations:self.myCache.annotationsInterMediateState withCompletion:^{
[self movePinsToDestinations:self.myCache.annotationsWeShouldbeDisplaying withCompletion:^{
}];
}];
Update:
Out of curiosity I nested the animation several times.
[self movePinsToDestinations:self.myCache.annotationsInterMediateState withCompletion:^{
[self movePinsToDestinations:self.myCache.annotationsWeShouldbeDisplaying withCompletion:^{
[self movePinsToDestinations:emptyAnnotations withCompletion:^{
[self movePinsToDestinations:startOff withCompletion:^{
[self movePinsToDestinations:self.myCache.annotationsInterMediateState withCompletion:^{
[self movePinsToDestinations:self.myCache.annotationsWeShouldbeDisplaying withCompletion:^{
}];
}];
}];
}];
}];
}];
Here is the result:
21:51.9 Start Animating: Start Animating
21:51.9 (animationTime): 10
21:51.9 Reach Completion Block: Reach Completion Block
21:51.9 Start Animating: Start Animating
21:51.9 (animationTime): 10
21:51.9 Reach Completion Block: Reach Completion Block
21:51.9 Start Animating: Start Animating
21:51.9 (animationTime): 10
22:01.9 Reach Completion Block: Reach Completion Block
22:01.9 Start Animating: Start Animating
22:01.9 (animationTime): 10
22:01.9 Reach Completion Block: Reach Completion Block
22:01.9 Start Animating: Start Animating
22:01.9 (animationTime): 10
22:01.9 Reach Completion Block: Reach Completion Block
22:01.9 Start Animating: Start Animating
22:01.9 (animationTime): 10
22:01.9 Reach Completion Block: Reach Completion Block
So one of the animation is done properly and the block is called 10 seconds after start animating.
It is possible that the block is called immediately because another animation is being called in viewDidAddAnnotation, however, it's unlikely to be the case because many different animations can be called at the same time.
Most animation still run for a mere miliseconds. Some run for 3 seconds. No other animation should be running.
Upvotes: 1
Views: 397
Reputation: 33138
This is actually a feature. When nothing is animated then the animation finish immediately. I wonder if there is an option to change that.
Sometimes this is a good thing. The thing is while there is nothing animated within the existing animation, the added animation need animation independently. The end result is the animation of added pinview is not in sync with the animation of the existing pinView
Doing self.ReloadBut.alpha = (float) random()/RAND_MAX;
, for example, fix the problem.
I wonder if there is a more elegant way where I can just perform the whole animation on didAddAnnotationViews. Alternatively I can have a hidden view moving around in case I know that some new pins are added.
It's kinf of nice to be able to animate newly added pins at the same time with existing pins. I'll think about it.
Upvotes: 1
Reputation: 56129
It is possible that the block is called immediately because another animation is being called in viewDidAddAnnotation
This is almost certainly the cause. You can have multiple animations going, but if two animations acting on the same object overlap, the first animation is interrupted (jumps to the end by default, but you can set an option to resume from where it was). Comment out your second animation to confirm.
Upvotes: 3