1
votes

I'm trying to implement the same map behaviour has Uber. I would like to keep the map centered while the user zoom the map with a pinch or a double tap. I tried implementing my own gesture recognizer but the result isn't great... Does anyone got an idea of how to do it ?

Thanks !

2

2 Answers

1
votes

For those interested in the solution i managed to do it.

First you need to add your gesture recognizer in the viewDidload

UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinchOnMap:)];
[pinch setDelegate:self];
[pinch setDelaysTouchesBegan:YES];
[self.mapGestureContainer addGestureRecognizer:pinch];

UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(zoomInGesture:)];
gestureRecognizer.delegate = self;
[gestureRecognizer setDelaysTouchesBegan:YES];
gestureRecognizer.numberOfTapsRequired = 2;
[self.mapGestureContainer addGestureRecognizer:gestureRecognizer];

Then implement the gesture function, it will handle the zoom based on the pinch scale. I added a small delay to avoid too much processing.

-(void) zoomInGesture:(UITapGestureRecognizer *) recognizer {
    currentRegion = self.mapView.region;
    currentSpan = self.mapView.region.span;
    isZoomingWithDoubleTap = YES;

    MKCoordinateRegion region = currentRegion;
    MKCoordinateSpan span = currentSpan;

    span.latitudeDelta = currentSpan.latitudeDelta / 2.3;
    span.longitudeDelta = currentSpan.longitudeDelta / 2.3;
    region.span = span;

    [self.mapView setRegion:region animated:YES];
}

//Gesture used when the user pinch the area of the map
- (void) pinchOnMap:(UIPinchGestureRecognizer *) recognizer {

    if (recognizer.state == UIGestureRecognizerStateBegan) {
        isPinching = YES;
        self.mapView.scrollEnabled = NO;
        self.mapView.userInteractionEnabled = NO;

        currentRegion = self.mapView.region;
        currentSpan = self.mapView.region.span;
        lastZoomTime = [[NSDate date] timeIntervalSince1970];
    }

    if (recognizer.state == UIGestureRecognizerStateEnded) {
        isPinching = NO;
        self.mapView.scrollEnabled = YES;
        self.mapView.userInteractionEnabled = YES;
    }

    if (recognizer.state == UIGestureRecognizerStateChanged) {
        if (([[NSDate date] timeIntervalSince1970] * 1000) - lastZoomTime >= 20) {
            lastZoomTime = [[NSDate date] timeIntervalSince1970] * 1000;

            MKCoordinateRegion region = currentRegion;
            MKCoordinateSpan span = currentSpan;
            span.latitudeDelta = currentSpan.latitudeDelta / recognizer.scale;
            span.longitudeDelta = currentSpan.longitudeDelta / recognizer.scale;
            region.span = span;
            [self.mapView setRegion:region animated:NO];
        }
    }
}
0
votes

In your map view delegate, do this

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation 
{
   [mapView setCenterCoordinate:userLocation.location.coordinate animated:YES];
}