尝试使用didSelectAnnotationView和didDeselectAnnotationView在子视图内外动画制作动画

时间:2012-10-31 19:39:35

标签: iphone ios mkmapview mkannotation uiviewanimation

我在MKMapView上设置了多个注释。在单击某个引脚时,我不想使用地图注释标注,而是想要将子视图(self.detailView)设置为屏幕底部的动画,并在未选择任何内容时将其移回。当用户选择了一个引脚,然后选择另一个引脚时,我希望我的视图在屏幕上显示动画,然后立即在屏幕上设置动画(当然,该信息对应于新选择的注释)。

在没有考虑太多的情况下,我尝试了一件容易的事情 - 选择注释时,将self.detailView设置为屏幕动画,取消选择时,屏幕上显示self.detailView动画:

- (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会快速连续触发,则两个动画都会尝试同时运行,并且结果,效果不能正常工作。通常情况下,我会通过将第二个动画放在第一个动画的完成块中来将动画链接在一起,但由于它们采用不同的方法,我显然不能在这里做到。

任何人对如何解决这个问题都有任何想法?谢谢!

1 个答案:

答案 0 :(得分:2)

可能有更好的方法来做你想做的事,但我会首先回答你的具体问题。

在控制器中实现控制动画关闭再打开的视图的公共方法:

- (void)showInfoView:(MyInfoClass*)theInfo;
- (void)hideInfoView;

showInfoView中设置一个标记,显示/显示并在屏幕上显示动画 - 在一个块中执行此代码并立即调用它以使其像这样工作...

dispatch_block_t showBlock = ^
{
    self.isShowing = YES;
    /* show code goes here */
};
showBlock();

hideInfoView中,您可以为其设置动画并取消设置动画完成块中的标记。

现在在showInfoView之前调用showBlock检查标志以确保它尚未显示 - 如果是,那么不是立即执行该块,而是将其添加到{{1}的末尾调用NSMutableArray。然后在toShowBlocks中取消设置标志之前检查hideInfoView数组是否为空,如果不是,则删除并调用第一项(使用数组作为FIFO队列),如下所示... < / p>

toShowBlocks

然后你只需要在选择/取消选择引脚时调用你的show并隐藏方法,这将为你处理它。这应该至少让你走上正确的道路。

也许是更好的方式:

上面有一些问题,动画视图可能会隐藏并显示很多,如果用户坚持按下引脚,导致在用户获得最后一个动画之前的长动画队列。此外,当用户平移和缩放地图时,视图不会像注释那样遵循地图。因此,您可能最好为信息视图使用自定义注释。这是一个真正的痛苦,因为dispatch_block_t nextShowBlock = [toShowBlocks objectAtIndex:0]; [toShowBlocks removeObjectAtIndex:0]; nextShowBlock(); 视图的行为不像常规MKAnnotation,这会导致各种各样的问题。不过,我在这个答案中描述了一种使用UIView作为自定义标注的方法:https://stackoverflow.com/a/8649951/461492