Detect GMSMapView zoom
Asked Answered
K

4

7

Is there a way, to detect zoom (pinch and double tap) in this Google Map Services component?

- (void)mapView:(GMSMapView *)mapView willMove:(BOOL)gesture

Above method fire regardless of the movement made.

Korry answered 29/3, 2014 at 18:10 Comment(0)
B
9

There's an another way to detect whenever zoom (or any other property for that matter) has been changed - Key-Value-Observing (aka KVO). It's especially useful when there's no delegate method provided for us to use. From Apple docs:

Key-value observing provides a mechanism that allows objects to be notified of changes to specific properties of other objects.

Wherever you set up your map view add this snippet:

[self.mapView addObserver:self forKeyPath:@"camera.zoom" options:0 context:nil];

Now you only have to implement -observeValueForKeyPath:ofObject:change:context: method to actually receive a callback. Like so:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

if ([keyPath isEqualToString:@"camera.zoom"]) {

    // this static variable will hold the last value between invocations.
    static CGFloat lastZoom = 0;

    GMSMapView *mapView = (GMSMapView *)object;
    CGFloat currentZoom = [[mapView camera] zoom];

    if (!(fabs((lastZoom) - (currentZoom)) < FLT_EPSILON)) {

        //Zoom level has actually changed!
        NSLog(@"Zoom changed to: %.2f", [[mapView camera] zoom]);

    }

    //update last zoom level value.
    lastZoom = currentZoom;

    }
}

Don't forget to remove observer in -dealloc or -viewDidDissapear depending on your needs:

- (void)dealloc {

    [self.mapView removeObserver:self forKeyPath:@"camera.zoom"];

}

Happy coding :-)

Backsight answered 26/5, 2015 at 11:43 Comment(0)
I
4

I hope you have used GMSMapViewDelegate in header file

use following code in implementation file which is delegate of GMSMapView object

-(void)mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition*)position {
   float zoom = mapView.camera.zoom;
   // handle you zoom related logic
}
Intosh answered 23/4, 2014 at 15:29 Comment(0)
B
4

Swift 3
Following code worked for me:

func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition) {
    print("Pinched or tapped on the map")
}

When the user Zoom (double taps or pinch) on the screen this method is called once.

Britain answered 18/9, 2017 at 13:13 Comment(1)
This method will be triggered when the camera does anything at all, not just zooming/pinching... So even a panning gesture, a camera reset programmatically etc will trigger it.Spinoza
T
1

Some old, but still... You can detect this way, first say mapView to consume gestures in view:

    mapView.settings.consumesGesturesInView = true

    for gestureRecognizer in mapView.gestureRecognizers! {
        gestureRecognizer.addTarget(self, action: "handleMapGesture:")
    }

Second, on your function, check for 2 things, state and number of touches.

If state is .Changed, gesture begin and with 2 touches is the zoom pinch.

The hard one is double tap, you have to implement some kind of late listener and chain the last two gestures, the way to identified a "Tap" is with just .Begin and .End and one touch, there isn't .Changed state for this kind of gesture.

Note: this works on Swift 2, not tested on 3 or 4

Twinkle answered 14/3, 2016 at 8:20 Comment(4)
It's an overkill, just sayingAdria
@Adria well, the idea is to share knowledge, right? Don't make sense your comment, unless there's some technical implications on what I propose to use, if this is the case, please, share your knowledgeTwinkle
Your complexity is O(n) while other simpler solutions aren't. Not saying it won't work...Adria
Actually, this was suuuuper useful. When you disable panning, and leave zoom (setting geofence radius) it seems to kill a bunch of delegate functions that would otherwise detect this. With some conditional checking in there, this has saved my day. There is only one gesture recogniser, btw, so no need to iterate. .first is adequate.Modestamodeste

© 2022 - 2024 — McMap. All rights reserved.