Objective c 为注释的移除设置动画

Objective c 为注释的移除设置动画,objective-c,ios,mkmapview,mkannotation,mkannotationview,Objective C,Ios,Mkmapview,Mkannotation,Mkannotationview,我有一个地图和一组注释,每个注释都有一个“parent”属性。当前,当我添加注释时,我实现了didAddAnnotationViews方法来设置这些注释的动画,使它们看起来来自其父坐标。在删除注释的过程中是否有这样做的方法?当我从地图上删除注释时,我希望将其动画化到其父坐标,据我所知,删除注释时没有与DidAddAnnotationView等效的方法。将注释动画化,然后将其从地图上删除,并在动画完成后执行删除。代码可能如下所示: - (void) removeMyAnnotation:(MyAn

我有一个地图和一组注释,每个注释都有一个“parent”属性。当前,当我添加注释时,我实现了didAddAnnotationViews方法来设置这些注释的动画,使它们看起来来自其父坐标。在删除注释的过程中是否有这样做的方法?当我从地图上删除注释时,我希望将其动画化到其父坐标,据我所知,删除注释时没有与DidAddAnnotationView等效的方法。

将注释动画化,然后将其从地图上删除,并在动画完成后执行删除。代码可能如下所示:

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

您应该而不是延迟调用removeAnnotation,就像@Vladimir的回答一样,因为MKMapView的状态可以在动画期间更改

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

我为MKMapView编写了此类别,您可以使用它安全地删除动画注释:

@interface MKMapView (RemoveAnnotationWithAnimation)

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

@end
@interface MKMapView(用动画移除注释)
-(void)removeAnnotation:(id)注释动画:(BOOL)动画;
-(void)removeAnnotations:(NSArray*)注释动画:(BOOL)动画;
@结束
和.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
@implementation MKMapView(用动画移除注释)
-(void)removeAnnotation:(id)注释已设置动画:(BOOL)已设置动画
{
[self-removeAnnotations:@[annotation]已设置动画:已设置动画];
}
-(void)removeAnnotations:(NSArray*)已设置动画的批注:(BOOL)已设置动画
{
如果(动画){
NSSet*visibleAnnotations=[self-annotationsInMapRect:self.visibleMapRect];
NSMutableArray*annotationsToRemoveWithAnimation=[NSMutableArray];
用于(注释中的id注释){
if([visibleAnnotations containsObject:annotation]){
[annotationsToRemoveWithAnimation addObject:annotation];
}
}
NSMutableArray*快照视图=[NSMutableArray];
用于(annotationsToRemoveWithAnimation中的id注释){
UIView*annotationView=[self-viewForAnnotation:annotation];
如果(注释视图){
UIView*snapshotView=[annotationView SnapshotViewAfterScreen更新:否];
snapshotView.frame=annotationView.frame;
[快照视图添加对象:快照视图];
[[annotationView superview]插入子视图:子视图上方的快照视图:annotationView];
}
}
[UIView animateWithDuration:0.5
动画:^{
用于(快照视图中的UIView*快照视图){
//如果需要,请更改视图的动画方式
CGRect frame=snapshotView.frame;
frame.origin.y=-frame.size.height;
snapshotView.frame=帧;
}
}
完成:^(布尔完成){
用于(快照视图中的UIView*快照视图){
[快照视图从SuperView移除];
}
}];
}
[自我移除注释:注释];
}
@结束

谢谢-还有一件事,有没有办法访问注释对应的MKAnnotationView,这样我就可以用这种方式移动注释了?因为我的注释类是动态计算其坐标的,所以无法对其进行设置(除非我添加了大量设置自定义坐标的功能,这是我宁愿避免的)。@benwad,您可以使用MKMapView中的viewForAnnotation方法获得它,尽管它不能保证总是返回实际视图(例如,如果注释不可见,它可以返回nil)@indiekiduk,检查问题-在其条件下,每个批注都有parentAnnotation作为属性Hey Vladimir我需要您的帮助查看此问题,如果您有任何想法,请提供帮助。我实施此解决方案是为了淡出批注。当快照视图淡出时平移地图时,这不起作用,因为它们将保持不变,而地图移动。看起来很奇怪。在阅读了您的评论并考虑了@Vladimir的解决方案后,我看不出在动画期间添加或删除不同的注释如何影响在完成块执行时删除特定注释的能力。该块捕获指针,因此它具有精确的注释to删除。我能看到的唯一问题是,是否有其他代码删除了正在制作动画的注释。我不确定
MKMapView
如果没有您试图删除的注释,它会做什么。@duncc4问题是MKMapView重用注释视图实例,就像UITableView对其单元格所做的那样。因此,如果存储指向要删除的批注的指针并将地图滚动到其他批注组,在执行块时,您可能最终删除错误的批注。如果您存储了可能会发生的MKAnnotationView,但如果存储了MKAnnotation,又会发生什么情况,因为MKMapView不重用MKAnnotations?是的,正确。我记得我在Vladimir的解决方案,不得不提出我自己的解决方案。不幸的是,我记不清所有的细节。总的来说,我仍然认为演示文稿的更新应该与模型的更新一起完成。当涉及到时间和延迟模型的更新时,请注意演示文稿的意外状态。