Custom Map Callout Animation

I have to create custom MKMapView annotations, which look almost the same as the ones iOS provides, but have different color (white) and slightly different shape.

My first attempt was to prevent opening the original black UIAnnotationView s and in AnnotationView 's setSelected:animated: added a new subview to the same UIAnnotationView . I have animated this view after adding it to the superview. This had only one problem: my custom button in the annotation was not clickable.

After this I've found this excellent example:

https://github.com/tochi/custom-callout-sample-for-iOS

This adds a new CalloutAnnotation to the map when the user clicks on a PinAnnotation . PinAnnotation s have no AnnotationView s, only CalloutAnnotation s do.

This works fine, except that I can't figure out how to do the iOS-like initial zooming animation on the annotation views when they are created.

The animation I want to use is the following (found here on SO and worked fine with my first attempt):

- (void)animateCalloutAppearance:(CalloutAnnotationView *)annotaitonView
{
    self.endFrame = annotaitonView.frame;
    CGFloat scale = 0.001f;
    annotaitonView.transform = CGAffineTransformMake(scale, 0.0f, 0.0f, scale, [self xTransformForScale:scale andAnnotation:annotaitonView], [self yTransformForScale:scale]);

    [UIView animateWithDuration:0.075f delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
        CGFloat scale = 1.2f;
        annotaitonView.transform = CGAffineTransformMake(scale, 0.0f, 0.0f, scale, [self xTransformForScale:scale andAnnotation:annotaitonView], [self yTransformForScale:scale]);
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:0.1 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
            CGFloat scale = 0.90;
            annotaitonView.transform = CGAffineTransformMake(scale, 0.0f, 0.0f, scale, [self xTransformForScale:scale andAnnotation:annotaitonView], [self yTransformForScale:scale]);
        } completion:^(BOOL finished) {
            [UIView animateWithDuration:0.075 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
                CGFloat scale = 1.0;
                annotaitonView.transform = CGAffineTransformMake(scale, 0.0f, 0.0f, scale, [self xTransformForScale:scale andAnnotation:annotaitonView], [self yTransformForScale:scale]);
            } completion:nil];
        }];
    }];
}

#pragma mark - The helper methods

- (CGFloat)relativeParentXPosition:(CalloutAnnotationView *)annotationView {
    return annotationView.bounds.size.width / 2.0f;
}

- (CGFloat)xTransformForScale:(CGFloat)scale andAnnotation:(CalloutAnnotationView *)annotationView {
    CGFloat xDistanceFromCenterToParent = self.endFrame.size.width / 2.0f - [self relativeParentXPosition:annotationView];
    CGFloat transformX = (xDistanceFromCenterToParent * scale) - xDistanceFromCenterToParent;

    return transformX;
}

- (CGFloat)yTransformForScale:(CGFloat)scale {
    CGFloat yDistanceFromCenterToParent = self.endFrame.size.height / 2.0f;
    CGFloat transformY = yDistanceFromCenterToParent - yDistanceFromCenterToParent * scale;

    return transformY;
}

I've found the answer on this blog: http://blog.asynchrony.com/2010/09/building-custom-map-annotation-callouts-part-1/

The tricky part is that you have to do the animation in the CalloutAnnotationView 's didMoveToSuperView :)

- (void)didMoveToSuperview
{
    [self animateCalloutAppearance:self];
}

I hope it helps somebody else :)

链接地址: http://www.djcxy.com/p/67282.html

上一篇: IOS:如何绘制和计算IOS 6中自定义标注箭头的位置?

下一篇: 自定义地图标注动画