I'm trying to animate a some subviews of a subview of an annotation view.
So, to be more clear, the gray pin is my annotation view, which has an invisible subview, and this subview contains those 4 colored circle views.
annotation view
| invisible view (called typeSelectionView)
| yellow view (called typeButton)
| blue view (called typeButton)
| green view (called typeButton)
| red view (called typeButton)
First the circles are not visible (transform scale (0, 0) and their center at the head of the gray pin), then, when I select the gray pin, those circles come from the pin head growing and moving to their original position (the one on the picture above).
When I deselect the pin, the opposite animation happens.
And when I select and deselect (or the opposite) before the animation is finished, it changes the way it was going (if it was growing it shrinks) reverting the animation in the middle. That is why I need the UIViewAnimationOptionBeginFromCurrentState
.
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)annotationView
{
// in case the typeSelectionView was already being showed by another annotationView
if (self.typeSelectionView.superview != annotationView) {
[self.typeSelectionView removeFromSuperview];
[self.typeSelectionView showTypeButtons:NO animated:NO completion:NULL];
}
[annotationView addSubview:self.typeSelectionView];
[self.typeSelectionView showTypeButtons:YES animated:YES completion:NULL];
}
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)annotationView
{
if (self.typeSelectionView.superview) {
[self.typeSelectionView showTypeButtons:NO
animated:YES
completion:^(BOOL finished) {
if (finished) {
[self.typeSelectionView removeFromSuperview];
}
}];
}
}
- (void)showTypeButtons:(BOOL)show animated:(BOOL)animated completion:(void (^)(BOOL))completion
{
void (^block)(void) = ^{
for (int i = 0; i < self.typeButtons.count; i++) {
TypeButton *typeButton = self.typeButtons[i];
if (show) {
typeButton.center = [self _typeButtonCenterForIndex:i numberOfButtons:self.typeButtons.count];
typeButton.transform = CGAffineTransformIdentity;
} else {
typeButton.center = CGPointMake(viewWidth / 2, viewheight + 5); // pin head center
typeButton.transform = CGAffineTransformMakeScale(0, 0);
}
}
};
if (animated) {
[UIView animateWithDuration:0.5
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:block
completion:^(BOOL finished) {
if (completion) {
completion(finished);
}
}];
} else {
block();
if (completion) {
completion(YES);
}
}
}
So far no problem, but when one gray pin is displaying the typeSelectionView (like in the picture above) and then I select another pin, it's like this part:
if (self.typeSelectionView.superview != annotationView) {
[self.typeSelectionView removeFromSuperview];
[self.typeSelectionView showTypeButtons:NO animated:NO completion:NULL];
}
did nothing.
The 4 circles simple jump from one pin to the other without any animation.
What I would expect is that the [self.typeSelectionView showTypeButtons:NO animated:NO completion:NULL];
set those buttons to be "hidden" (scale (0, 0) and center in the head of the pin) without any animation (because the invisible view doesn't have a superview anymore, so they are not even showing), and then when I add the typeSelectionView to the new annotationView with [annotationView addSubview:self.typeSelectionView];
, I animate the circles to their original position again with [self.typeSelectionView showTypeButtons:YES animated:YES completion:NULL];
.
Btw, doing [typeButton.layer removeAllAnimations]
at the beginning of showTypeButtons:animated:completion:
does nothing.
How do I solve this?
Thanks in advance.
EDIT: (BONUS if someone can explain that to me... and help me solve it) =)
Suppose the circles are showing like in the picture above, then this code:
NSLog(@"type selected");
[self.typeSelectionView showTypeButtons:NO
animated:YES
completion:^(BOOL finished) {
NSLog(@"finisheddddd: %d", finished);
}];
[self.typeSelectionView showTypeButtons:NO
animated:YES
completion:^(BOOL finished) {
NSLog(@"finished: %d", finished);
}];
generates the following output:
type selected
finished: 1
finisheddddd: 1
So the second animation finishes first and both animations finish with finished == YES
.
Also the second animation (which finishes first) finishes instantly and not after the end of the animation time.
O.o