iOS GoogleMaps SDK - animateToCameraPosition 动画完成后的处理程序?

13

目前我正在使用GoogleMaps SDK for iOS进行各种操作。在调用时

[self.googleMapsView animateToCameraPosition:[GMSCameraPosition 
                            cameraWithLatitude:LATITUDE
                                     longitude:LONGITUDE
                                          zoom:ZOOM]];

是否有完成处理程序来确定动画是否已完成?

当然,我可以通过GMSMapViewDelegate获取有关cameraPosition的更新,但是我该如何检查动画是否已完成?

- (void)mapView:(GMSMapView *)mapView 
didChangeCameraPosition:(GMSCameraPosition *)position;

2
关于相关内容:didChangeCameraPosition在简单的滑动或缩放手势中被调用多次(10+次),而不仅仅在地图已经改变后被调用一次。 - brendan
我在这方面遇到了麻烦,因为每次调用这个委托方法时,我都会使用从Google Maps API检索到的新地址更新一个文本字段,并且它被调用了很多次,以至于我收到了OVER_QUERY_LIMIT的错误。 - David Cespedes
5个回答

19

为了参考这篇帖子未来的读者,2013年7月发布的Google Maps SDK for iOS版本1.4.0添加了一个新的委托方法mapView:idleAtCameraPosition:,该方法将在任何镜头移动结束时被触发-无论是像这个问题中的编程动画还是用户触发的移动。


9
这可能有效(我没有尝试过):
[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithFloat: 1.0f] forKey:kCATransactionAnimationDuration];
[self.googleMapsView animateToCameraPosition:[GMSCameraPosition 
                        cameraWithLatitude:LATITUDE
                                 longitude:LONGITUDE
                                      zoom:ZOOM]];
[CATransaction setCompletionBlock:^{
    // ... whatever you want to do when the animation is complete
}];
[CATransaction commit];

基本上,这会创建一个动画事务,可以动画化您的相机移动(更改numberWithFloat:的值以更改速度),并设置自己的完成块来说明在动画结束时想要做什么。 [CATransaction commit]是触发动画的方法。
注意:此答案部分基于此答案

抱歉,我们如何使用这段代码?我不明白需要将其放在哪里! - francesco.venica
2
这对我没有起作用。完成块在动画结束之前被调用。 - Zigglzworth
1
为了使其正常工作,完成块需要在动画代码之前定义。 - palpoms

3

最近我遇到了谷歌动画方法缺乏完成处理程序的问题。
到目前为止,我发现的最佳解决方案是通过CATransation API附加自己的完成处理程序。

private func attachCompletionHandlerToGoogleAnimations(@noescape animations: () -> Void, #completion: (() -> Void)!) {
    CATransaction.begin()
    CATransaction.setCompletionBlock(completion)
    animations()
    CATransaction.commit()
}

使用示例:

attachCompletionHandlerToGoogleAnimations({
    googleMapView.animateToLocation(coordinate)
}) {
    println("camera moved to location \(coordinate)")
}

2
我不认为有这样的方法,但是...
迄今为止对我有效的方法是设置一个计时器,在位置停止更新后(非常)短时间内触发:
- (void)mapView:(GMSMapView*)mapView didChangeCameraPosition:(GMSCameraPosition*)position {
  // _panTimer is an instance variable of the delegate.
  [_panTimer invalidate];
  _panTimer = [NSTimer timerWithTimeInterval:0.2
                                      target:self
                                    selector:@selector(_mapHasStoppedMoving)
                                    userInfo:nil
                                     repeats:NO];
  [[NSRunLoop currentRunLoop] addTimer:_panTimer forMode:NSDefaultRunLoopMode];
}

但是如果用户只是进行了小的更改呢?计时器不会失效,mapHasStoppedMoving也不会被调用。 - David Cespedes
任何更改都会导致该方法最终被触发。_panTimer是管理GMSMapView的类的ivar,也称为mapView的代理。 - andybons
这是我在1.1.2中的做法。GMS问题跟踪器上有一个增强请求,用于更改后的委托方法。 - Daij-Djan

1

SWIFT 版本示例:

let vancouver = CLLocationCoordinate2D(latitude: 49.26, longitude: -123.11)
let calgary = CLLocationCoordinate2D(latitude: 51.05,longitude: -114.05)
let bounds = GMSCoordinateBounds(coordinate: vancouver, coordinate: calgary)
let cameraPosition = GMSCameraUpdate.fit(bounds)

CATransaction.begin()
CATransaction.setValue(1.0/*duration in seconds*/, forKey: kCATransactionAnimationDuration)
CATransaction.setCompletionBlock({
    print("animation complete, do whatever you want here")
})
mMapView.animate(with: cameraPosition)
CATransaction.commit()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接