我在 MKMapView 上设置了多个注释。我不想在单击图钉时使用 map 注释标注,而是希望将 subview (self.detailView
) 动画化到屏幕底部,并在未选择任何内容时将其移回。当用户选择了一个图钉,然后选择另一个图钉时,我希望我的 View 在屏幕外进行动画处理,然后立即以动画方式返回到屏幕上(当然,具有与新选择的注释相对应的不同信息)。
没有想太多,我尝试了看似简单的事情 - 当选择注释时,将 self.detailView
动画到屏幕上,当取消选择时,将 self.detailView 动画化。屏幕外的详细 View
:
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
NSLog( @"selected annotation view" );
[UIView animateWithDuration:0.2f
delay:0.0f
options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
animations:^{
[self.detailView setFrame:CGRectMake(0, 307, 320, 60)];
}
completion:^(BOOL finished){
}];
}
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
NSLog( @"deselected annotation view" );
[UIView animateWithDuration:0.2f
delay:0.0f
options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
animations:^{
[self.detailView setFrame:CGRectMake(0, 367, 320, 60)];
}
completion:^(BOOL finished){
}];
}
当未选择图钉并且用户选择图钉时,以及当选择图钉并且用户通过单击空白区域取消选择它时,此功能可以正常工作。当然,当已经选择了一个图钉时,就会出现问题:如果用户单击另一个图钉,didDeselectAnnotationView
和 didSelectAnnotationView
会快速连续触发,两个动画都会尝试运行同时,导致效果无法正常发挥。通常,我会通过将第二个动画放入第一个动画的完成 block 中来将动画链接在一起,但由于它们位于不同的方法中,所以我显然不能在这里这样做。
有人对我如何解决这个问题有任何想法吗?谢谢!
最佳答案
可能有更好的方法来做你想做的事,但我会先回答你的具体问题。
在 Controller 中实现公共(public)方法来控制动画关闭和再次打开的 View :
- (void)showInfoView:(MyInfoClass*)theInfo;
- (void)hideInfoView;
在 showInfoView
中,您设置一个显示/正在显示的标志,并在屏幕上为它设置动画 - 在 block 中执行此代码并立即调用它,只是为了让它像这样工作...
dispatch_block_t showBlock = ^
{
self.isShowing = YES;
/* show code goes here */
};
showBlock();
在 hideInfoView
中,您可以将其关闭并取消设置动画完成 block 中的标志。
现在,在调用 showBlock
之前,在 showInfoView
中检查该标志以确保它尚未显示 - 如果已显示,则不要立即执行该 block ,而是将其添加到名为 toShowBlocks
的 NSMutableArray
的末尾。然后在 hideInfoView
中取消设置标志之前检查 toShowBlocks
数组是否不为空,如果不是,则删除并调用第一个项目(使用数组作为 FIFO 队列)像这样...
dispatch_block_t nextShowBlock = [toShowBlocks objectAtIndex:0];
[toShowBlocks removeObjectAtIndex:0];
nextShowBlock();
然后,您只需在选择/取消选择引脚时调用显示和隐藏方法,这将为您处理。这至少应该让你走上正确的道路。
也许是更好的方法:
上述内容存在一些问题,如果用户疯狂地按图钉,动画 View 可能会被隐藏并多次显示,从而导致在用户获得最后一个动画之前出现冗长的动画队列。此外, View 不会像用户平移和缩放 map 时的注释那样跟随 map 移动。因此,您最好为信息 View 使用自定义注释。这是一个真正的痛苦,因为 MKAnnotation
View 的行为与常规 UIView
不同,这会导致各种问题。不过,我在此答案中描述了一种使用 MKAnnotation
作为自定义标注的方法:https://stackoverflow.com/a/8649951/461492 .
关于iphone - 尝试使用 didSelectAnnotationView 和 didDeselectAnnotationView 对 subview 进行动画处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13166289/