You can see the problem comparing two gifs below. Both "shrink" and "stretch" animation are based on constraints manipulation and [self layoutIfNedeed]
is placed inside -animateWithDuration
block. As you can see it works as intended when the map is not moving. But "shrink" animation happens instantly as you start dragging the map. If you look closely you might notice that cornerRadius animation still works. This tells me that it might have something to do with map (scrollView inside? no idea how google map works) calling it's own layout blocks that interfere with my animation. Or it might be due to the fact that cornerRadius animation is done using CABasicAnimation, not UIView animation.
Animated InfoView is not a subview of the mapView. Not sure if it should affect my infoView's layout when mapView is calling inner layout methods.
I've tried all the options combined UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionOverrideInheritedDuration | UIViewAnimationOptionOverrideInheritedOptions
just to see if it helps. It does not.
I think I can overcome this manipulating frame directly instead of manipulating constraints and it will look the same to the user, but I feel like using constraints is so much more elegant. I try to avoid manipulating frames as much as possible and use autolayout.
Any ideas what's causing this and how to overcome this problem using autolayout animation?
UPDATE
I've tried animating frame directly - result is the same. So it has nothing to do with autolayout. It seems like current view animation is stopped for some reason.
If I replace my UIView animation block with CABasicAnimation it works like a charm.
I was asked to post some animation code:
- (void)shrink {
if (!self.isStretched) return;
self.stretched = NO;
[self hideImageAndLabels];
[self.indicatorView startAnimating];
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
animation.duration = duration;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.fromValue = @0;
animation.toValue = @(shrinkedSize / 2.0);
[self.layer addAnimation:animation forKey:@"cornerRadiusAnimationRounded"];
self.layer.cornerRadius = shrinkedSize / 2.0;
self.heightConstraint.constant = shrinkedSize;
self.widthConstraint.constant = shrinkedSize;
self.positionYConstraint.constant = 0;
self.triangleHeightConstraint.constant = 0;
self.trianglePositionYConstraint.constant = 14;
[UIView animateWithDuration:duration * 2 delay:0 usingSpringWithDamping:0.85 initialSpringVelocity:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
[self layoutIfNeeded];
} completion:^(BOOL finished) {
//
}];
}
I opened a bug on this issue with Google (https://code.google.com/p/gmaps-api-issues/issues/detail?id=10349), and this was their response:
Placing the UIView.animateWithDuration block inside a dispatch_async block worked for me.