【问题标题】:iOS GoogleMaps SDK - animateToCameraPosition animation finished handler?iOS GoogleMaps SDK - animateToCameraPosition 动画完成处理程序?
【发布时间】:2013-02-18 16:26:02
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 在相关方面:didChangeCameraPosition 在简单的滑动或捏合手势上也会被调用多次(10 次以上),而不是在地图更改后才被调用。
  • 我很痛苦,因为每当我使用从谷歌地图 API 检索到的新地址调用此委托方法时,我都会更新一个文本字段,并且它被调用了很多次,以至于我得到了 OVER_QUERY_LIMIT

标签: ios animation google-maps-mobile google-maps-sdk-ios


【解决方案1】:

为了这篇文章的未来读者参考,2013 年 7 月发布的适用于 iOS 的 Google Maps SDK 1.4.0 版添加了一个新的委托方法 ma​​pView:idleAtCameraPosition:,该方法将在末尾触发任何相机运动 - 无论是像这个问题中的程序动画还是用户触发的运动。

【讨论】:

  • 这正是我所需要的!谢谢!!
【解决方案2】:

这可能有效(我还没有尝试过):

[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] 是触发动画的原因。

注意:此答案部分基于this answer

【讨论】:

  • 抱歉,我们如何使用这段代码?我不明白我需要把它放在哪里!
  • 这对我不起作用。在动画结束之前调用完成块
  • 为此,需要在动画代码之前定义完成块。
【解决方案3】:

我不相信有,但是......

到目前为止,对我来说效果很好的一种方法是在位置停止更新后不久(非常)设置一个计时器:

- (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
  • 任何更改都会导致该方法最终被触发。 _panTimer 是管理 GMSMapView 的类的 ivar,也称为 mapView 的委托。
  • 这就是我在 1.1.2 中的做法。 GMS 问题跟踪器上有一个关于更改后委托方法的增强请求
【解决方案4】:

我最近遇到了 google 的动画方法缺少完成处理程序的问题。
到目前为止,我发现的最佳解决方案是通过 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)")
}

【讨论】:

    【解决方案5】:

    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()
    

    【讨论】:

      猜你喜欢
      • 2013-03-24
      • 2017-05-13
      • 1970-01-01
      • 2013-05-17
      • 1970-01-01
      • 1970-01-01
      • 2014-08-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多