动画到新的MKMapCamera后回调

时间:2014-01-05 01:41:44

标签: ios objective-c animation ios7 mkmapview

我希望在MKMapView动画后将方法调用为新的MKMapCamera

我首先使用此方法附加MKMapCamera

    [self.map setCamera:cam animated:YES];

此方法会导致动画但动画结束时不会通知我。 然后,在看到此SO post后,我尝试使用UIView动画块实现回调方法:

    MKMapCamera *cam = [[MKMapCamera alloc] init];
    cam.pitch = 75;
    cam.altitude = 125;
    [cam setCenterCoordinate:self.location.coordinate];

    [UIView animateWithDuration:3.0f animations:^{
        self.map.camera = cam;
    } completion:^(BOOL finished) {
        [self methodToImplement];
    }];

MKMapView仍有动画效果,但同时调用methodToImplement

谢谢!

2 个答案:

答案 0 :(得分:2)

看起来完成处理程序在这种情况下不能正常工作,所以你需要使用MKMapViewDelegate方法来更改区域。见WWDC 2013 - Putting Map Kit in Perspective

  

好了,现在我开始关闭这个动画,以便在动画完成时我需要知道的下一个相机,以便我可以动画到我们堆栈中的下一个相机。

     

嗯,你可能会想到在这里使用完成处理程序,但它会让你失望。

     

我知道会的。

     

不要使用该完成处理程序。

     

相反,您需要使用MKMapViews委托方法,该方法会告诉您区域更改何时完成。

如果您不打算使用很多不同类型的动画,那么只需使用mapView:regionDidChangeAnimated:方法并检查动画标记以调用'methodToImplement'(动画标记)即可。仅适用于因动画调用而导致的区域更改,而不是拖动地图等用户输入。

在我自己的项目中,我有一个更复杂的流程,所以我需要一个更灵活的解决方案,因此我选择在我的包含MKMapView的视图控制器中添加NSBlockOperation对象的NSMutableArray作为属性。对应于a的每个块操作都是我们不能使用的完成处理程序。 在mapView:regionDidChangeAnimated:我只是逐个弹出操作并执行它们:

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
    if (animated) {
        dispatch_async(dispatch_get_main_queue(), ^{
            while (self.mapRegionAnimationBlocks.count > 0) {
                NSBlockOperation* op = [self.mapRegionAnimationBlocks firstObject];
                [self.mapRegionAnimationBlocks removeObjectAtIndex:0];
                [op start];
            }
        });
    });

并且我想在那里使用该块的完成处理程序,我只是在调用动画代码之前添加到该数组:

dispatch_async(dispatch_get_main_queue(), ^{
    NSBlockOperation* op = [NSBlockOperation blockOperationWithBlock:^{
        [self methodToImplement];
    }];
    [self.mapRegionAnimationBlocks addObject:op];
});

[UIView animateWithDuration:3.0f animations:^{
    self.map.camera = cam;
} completion:NULL];

请注意,仅从单个线程(例如主线程)使用NSMutableArray很重要,因为它不是线程安全的。

我的解决方案有点破解,而且应该包含在MKMapView的类别或子类中,但我还没有解决这个问题。

答案 1 :(得分:0)

如果设置地图视图的委托,则可以编写mapViewDidFinishLoadingMap:,“告诉委托指定的地图视图已成功加载所需的地图数据。”

- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView
{
    // do whatever you want
}

如果您不仅想知道加载地图数据的时间,还想知道地图的渲染完成时(在iOS7 +中),您可以使用mapViewDidFinishRenderingMap,其中“告诉代表该地图视图已完成渲染所有可见的图块。“

- (void)mapViewDidFinishRenderingMap:(MKMapView *)mapView fullyRendered:(BOOL)fullyRendered
{        
    // do whatever you want
}

有关详细信息,请参阅MKMapViewDelegate Protocol Reference