动画移除注释
Posted
技术标签:
【中文标题】动画移除注释【英文标题】:Animate removal of annotations 【发布时间】:2012-01-23 17:47:54 【问题描述】:我有一个地图和一组注释,每个都有一个“父”属性。目前,当我添加注释时,我实现了 didAddAnnotationViews 方法来为这些注释设置动画,使它们看起来来自其父坐标。在删除注释期间有没有办法做到这一点?当我从地图中删除注释时,我希望它动画到它的父坐标,据我所知,当注释被删除时,didAddAnnotationViews 没有等效项。
【问题讨论】:
【参考方案1】:动画注释之前从地图中删除它并在动画完成后执行删除。代码可能如下所示:
- (void) removeMyAnnotation:(MyAnnotation*)annotation
[UIView animateWithDuration:1.0f
animations:^(void)
annotation.coordinate = annotation.parentAnnotation.coordinate;
completion:^(BOOL finished)completion
[mapView removeAnnotation:annotation];
【讨论】:
谢谢 - 另一件事,有没有办法访问注释的相应 MKAnnotationView 以便我可以这样移动它?因为我的注释类动态计算它的坐标,所以它不能被设置(除非我添加了一个设置自定义坐标的功能,我宁愿避免)。 @benwad,你可以使用 MKMapView 中的 viewForAnnotation 方法来获取它,虽然它不能保证总是返回实际视图(例如,如果注释不可见,它可以返回 nil) @indiekiduk,检查问题 - 在其条件下,每个注释都有 parentAnnotation 作为属性 嘿弗拉基米尔我需要你的帮助看看这个问题***.com/q/19268080/1468406如果你有任何想法请帮忙。【参考方案2】:您应该不推迟调用 removeAnnotation,就像在@Vladimir 的回答中一样,因为 MKMapView 的状态可能会在动画期间更改。
当从动画完成块调用 removeAnnotation 时,可能会在 MapView 中添加/删除另一个注释 - 因此,在某些情况下,您最终可能会删除错误的注释集。 p>
我为 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
【讨论】:
我实现了这个解决方案来淡化我的注释。这在快照视图淡出时平移地图时不起作用,因为它们会在地图移动时保持不变。看起来很奇怪。 在阅读了您的评论并考虑了@Vladimir 的解决方案后,我看不到在动画期间添加或删除不同的注释如何影响完成块执行时删除特定注释的能力。该块捕获指针,因此它具有要删除的确切注释。我能看到的唯一问题是其他代码是否删除了动画的确切注释。如果MKMapView
没有您要删除的注释,我不确定它会做什么。
@duncanc4 问题在于 MKMapView 重用了注释视图实例,就像 UITableView 对其单元格一样。因此,如果您存储指向要删除的注释的指针并将地图滚动到其他注释组,则最终可能会在块执行时删除错误的注释。
如果你存储了MKAnnotationView会发生什么,但是如果你存储了MKAnnotation,因为MKMapView不重用MKAnnotations怎么办?
是的,正确的。我记得我对 Vladimir 的解决方案有一些疑问,不得不提出自己的解决方案。不幸的是,我不记得所有的细节。总的来说,我仍然认为 Presentation 的更新应该与 Model 的更新一起进行。当涉及时间并且您延迟模型的更新时,请注意演示文稿的意外状态。以上是关于动画移除注释的主要内容,如果未能解决你的问题,请参考以下文章