简体   繁体   中英

iOS GoogleMaps SDK - animateToCameraPosition animation finished handler?

Currently I am using the GoogleMaps SDK for iOS for various operations. When calling

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

is there a completion handler to determine wether the animation finished or not?

Of course I get with the GMSMapViewDelegate updates about the cameraPosition but how should I check if the animation finished?

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

为便于以后的读者参考,2013年7月发布的iOS版Google Maps SDK 1.4.0已添加了一个新的委托方法mapView:idleAtCameraPosition:它将在任何照相机运动结束时触发-无论是像程序动画一样在这个问题或用户触发的动作。

This might work (I haven't tried it):

[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];

Basically, this creates an animation transaction that animates your camera movement (change the value for numberWithFloat: to change the speed) and you set your own completion block stating what you want to do when the animation is over. [CATransaction commit] is what fires the animation off.

Note: this answer partially based off this answer .

I don't believe there is, however...

A method that has worked well for me so far is to set a timer to fire (very) shortly after the location stops updating:

- (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];
}

I came across the issue of google's animation methods lacking completion handlers recently.
The best solution I've found so far is to attach my own completion handler via CATransation API.

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

Example usage:

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

SWIFT version example:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM