动画删除注释

发布于 2024-12-22 07:56:11 字数 189 浏览 1 评论 0原文

我有一张地图和一组注释,每个注释都有一个“父”属性。目前,当我添加注释时,我实现 didAddAnnotationViews 方法来对这些注释进行动画处理,以便它们看起来来自其父级的坐标。在删除注释期间有没有办法做到这一点?当我从地图中删除注释时,我希望它以动画方式显示到其父坐标,据我所知,在删除注释时没有 didAddAnnotationViews 的等效项。

I have a map and a set of annotations, each with a 'parent' property. Currently when I add annotations I implement the didAddAnnotationViews method to animate those annotations so they appear to come from their parent's coordinate. Is there a way of doing this during the removal of annotations? When I remove an annotation from the map I want it to animate in to its parent coordinate, and as far as I know there is no equivalent for didAddAnnotationViews for when an annotation is removed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一花一树开 2024-12-29 07:56:11

在从地图中删除注记之前对其进行动画处理,并在动画完成后执行删除操作。代码可能如下所示:

- (void) removeMyAnnotation:(MyAnnotation*)annotation{
   [UIView animateWithDuration:1.0f
                    animations:^(void){
                         annotation.coordinate = annotation.parentAnnotation.coordinate;
                    }
                    completion:^(BOOL finished)completion{
                        [mapView removeAnnotation:annotation];
                    }
}

Animate annotation before you remove it from the map and perform removal after animation is completed. The code may look like:

- (void) removeMyAnnotation:(MyAnnotation*)annotation{
   [UIView animateWithDuration:1.0f
                    animations:^(void){
                         annotation.coordinate = annotation.parentAnnotation.coordinate;
                    }
                    completion:^(BOOL finished)completion{
                        [mapView removeAnnotation:annotation];
                    }
}
木槿暧夏七纪年 2024-12-29 07:56:11

您不应该像 @Vladimir 的回答那样推迟调用 removeAnnotation ,因为 MKMapView 的状态可能会在动画过程中发生变化。

当从动画完成块调用 removeAnnotation 时,可以从 MapView 添加/删除另一个注释 - 因此,在某些情况下,您最终可能会删除错误的注释集。

我为 MKMapView 编写了这个类别,您可以使用它以安全的方式删除动画注释:

@interface MKMapView (RemoveAnnotationWithAnimation)

- (void)removeAnnotation:(id <MKAnnotation>)annotation animated:(BOOL)animated;
- (void)removeAnnotations:(NSArray *)annotations animated:(BOOL)animated;

@end

以及 .m 文件:

@implementation MKMapView (RemoveAnnotationWithAnimation)

- (void)removeAnnotation:(id <MKAnnotation>)annotation animated:(BOOL)animated
{
    [self removeAnnotations:@[annotation] animated:animated];
}

- (void)removeAnnotations:(NSArray *)annotations animated:(BOOL)animated
{
    if (animated) {
        NSSet * visibleAnnotations = [self annotationsInMapRect:self.visibleMapRect];
        NSMutableArray * annotationsToRemoveWithAnimation = [NSMutableArray array];
        for (id<MKAnnotation> annotation in annotations) {
            if ([visibleAnnotations containsObject:annotation]) {
                [annotationsToRemoveWithAnimation addObject:annotation];
            }
        }
        NSMutableArray * snapshotViews = [NSMutableArray array];
        for (id<MKAnnotation> annotation in annotationsToRemoveWithAnimation) {
            UIView * annotationView = [self viewForAnnotation:annotation];
            if (annotationView) {
                UIView * snapshotView = [annotationView snapshotViewAfterScreenUpdates:NO];
                snapshotView.frame = annotationView.frame;
                [snapshotViews addObject:snapshotView];
                [[annotationView superview] insertSubview:snapshotView aboveSubview:annotationView];
            }
        }
        [UIView animateWithDuration:0.5
                         animations:^{
                             for (UIView * snapshotView in snapshotViews) {
                                 // Change the way views are animated if you want
                                 CGRect frame = snapshotView.frame;
                                 frame.origin.y = -frame.size.height;
                                 snapshotView.frame = frame;
                             }
                         }
                         completion:^(BOOL finished) {
                             for (UIView * snapshotView in snapshotViews) {
                                 [snapshotView removeFromSuperview];
                             }
                         }];
    }
    [self removeAnnotations:annotations];
}

@end

You should NOT defer call of removeAnnotation like in @Vladimir's answer because state of MKMapView could be changed during the animation.

By the time the removeAnnotation is called from animation completion block, another annotations could be added / removed from the MapView - so, in some cases you can end up removing wrong set of annotations.

I wrote this category for MKMapView you can use for animated annotation removal in safe manner:

@interface MKMapView (RemoveAnnotationWithAnimation)

- (void)removeAnnotation:(id <MKAnnotation>)annotation animated:(BOOL)animated;
- (void)removeAnnotations:(NSArray *)annotations animated:(BOOL)animated;

@end

And the .m file:

@implementation MKMapView (RemoveAnnotationWithAnimation)

- (void)removeAnnotation:(id <MKAnnotation>)annotation animated:(BOOL)animated
{
    [self removeAnnotations:@[annotation] animated:animated];
}

- (void)removeAnnotations:(NSArray *)annotations animated:(BOOL)animated
{
    if (animated) {
        NSSet * visibleAnnotations = [self annotationsInMapRect:self.visibleMapRect];
        NSMutableArray * annotationsToRemoveWithAnimation = [NSMutableArray array];
        for (id<MKAnnotation> annotation in annotations) {
            if ([visibleAnnotations containsObject:annotation]) {
                [annotationsToRemoveWithAnimation addObject:annotation];
            }
        }
        NSMutableArray * snapshotViews = [NSMutableArray array];
        for (id<MKAnnotation> annotation in annotationsToRemoveWithAnimation) {
            UIView * annotationView = [self viewForAnnotation:annotation];
            if (annotationView) {
                UIView * snapshotView = [annotationView snapshotViewAfterScreenUpdates:NO];
                snapshotView.frame = annotationView.frame;
                [snapshotViews addObject:snapshotView];
                [[annotationView superview] insertSubview:snapshotView aboveSubview:annotationView];
            }
        }
        [UIView animateWithDuration:0.5
                         animations:^{
                             for (UIView * snapshotView in snapshotViews) {
                                 // Change the way views are animated if you want
                                 CGRect frame = snapshotView.frame;
                                 frame.origin.y = -frame.size.height;
                                 snapshotView.frame = frame;
                             }
                         }
                         completion:^(BOOL finished) {
                             for (UIView * snapshotView in snapshotViews) {
                                 [snapshotView removeFromSuperview];
                             }
                         }];
    }
    [self removeAnnotations:annotations];
}

@end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文