iphone - 尝试使用 didSelectAnnotationView 和 didDeselectAnnotationView 对 subview 进行动画处理

标签 iphone ios mkmapview mkannotation uiviewanimation

我在 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){

                      }];

}

当未选择图钉并且用户选择图钉时,以及当选择图钉并且用户通过单击空白区域取消选择它时,此功能可以正常工作。当然,当已经选择了一个图钉时,就会出现问题:如果用户单击另一个图钉,didDeselectAnnotationViewdidSelectAnnotationView 会快速连续触发,两个动画都会尝试运行同时,导致效果无法正常发挥。通常,我会通过将第二个动画放入第一个动画的完成 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 ,而是将其添加到名为 toShowBlocksNSMutableArray 的末尾。然后在 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/

相关文章:

iphone - 如何在按住 MenuItem 按钮时重复操作? (cocos2d)

ios - 我可以在CloudKit的生产环境中动态创建CKRecordZone吗

ios - 如何以编程方式获取标签栏的高度?

objective-c - MKMapView RegionDidChangeAnimated 由用户操作或程序调用

annotations - iOS 4.2 中的 map 注释和 MKMapView 有问题吗?

ios - 故障 map AnnotationView 行为

c# - MonoTouch 的性能问题?

iphone - 如何在iOS SDK中获取崩溃日志

ios - 如何查找特定字符在 NSString 中以大写形式出现的次数?

ios - Google Universal 中自定义维度的产品范围是什么