user1832451
user1832451

Reputation:

Center maps in iOS Programming

How do we follow the user in maps. I want to have the blue dot (user location) be in the center of the map, But I also what to allow the user to zoom in and zoom out and then after a couple seconds zoom in back in the user location.

My Educated Guess for the Solution: We detect if the user is zooming in or out, after three seconds of no zooming in or out detection, we starting follow the user :). Your HELP would be awesome :)

This code zoom in the user location but doesn't delay for zoom in and out:

     - (void)locationManager:(CLLocationManager *)manager
        didUpdateToLocation:(CLLocation *)newLocation
              fromLocation:(CLLocation *)oldLocation {

  MKCoordinateRegion userLocation = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 1500.0, 1500.0); [mapView setRegion:userLocation animated:YES];


    }

Upvotes: 7

Views: 5513

Answers (4)

Warif Akhand Rishi
Warif Akhand Rishi

Reputation: 24248

I had the same problem. I guessed:

  1. If the user drag the map, he wants to stay on that position.
  2. If the user do nothing or reset to show current location, I need to follow the user.

I added a reset button to show the current user location like this: enter image description here

On the reset button clicked, changed the needToCenterMap to TRUE

Added a drag gesture recognizer on map

// Map drag handler
    UIPanGestureRecognizer* panRec = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(didDragMap:)];



- (void)didDragMap:(UIGestureRecognizer*)gestureRecognizer {
    if (gestureRecognizer.state == UIGestureRecognizerStateEnded){
        NSLog(@"Map drag ended");
        self.needToCenterMap = FALSE;
    }
}

Followed the user on map depending on needToCenterMap flag

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

Upvotes: 1

yinkou
yinkou

Reputation: 5766

A quick look in the docs reveals the magic.
Set the userTrackingMode of your map to MKUserTrackingModeFollow.
See here.


Update:

Since you've updated your question, here's the new answer.
To recenter the map to the user location i would recommend to write a simple helper Method:

- (void)recenterUserLocation:(BOOL)animated{
    MKCoordinateSpan zoomedSpan = MKCoordinateSpanMake(1000, 1000);

    MKCoordinateRegion userRegion = MKCoordinateRegionMake(self.mapView.userLocation.coordinate, zoomedSpan);

    [self.mapView setRegion:userRegion animated:animated];
}

And now you should call it after a short delay if user has stopped moving the map. You can do this in the regionDidChange delegate method of the mapView.

But you can get problems if you don't lock the reset-method if the user changes the region multiple times before it really resets the map. So it would be wise to make a flag if it is possible to recenter the map. Like a property BOOL canRecenter.

Init it with YES and update the recenterUserLocation method to:

- (void)recenterUserLocation:(BOOL)animated{
    MKCoordinateSpan zoomedSpan = MKCoordinateSpanMake(1000, 1000);

    MKCoordinateRegion userRegion = MKCoordinateRegionMake(self.mapView.userLocation.coordinate, zoomedSpan);

    [self.mapView setRegion:userRegion animated:animated];

    self.canRecenter = YES;
}

Now you can call it safely after the user has moved the map in any way with a small delay:

- (void)mapView:(MKMapView *)mMapView regionDidChangeAnimated:(BOOL)animated{
    if (self.canRecenter){
        self.canRecenter = NO;
        [self performSelector:@selector(recenterUserLocation:) withObject:@(animated) afterDelay:3];
    }
}

Upvotes: 13

lukaswelte
lukaswelte

Reputation: 3001

I made a little example to show how you can delegate this job to the Map SDK. Of course you could listen to the Location change but MKUserTrackingModeFollow automatically does this for you, so just a single line of code

#import <MapKit/MapKit.h>

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    MKMapView *mapView = [[MKMapView alloc] initWithFrame:self.view.frame];

    //Always center the dot and zoom in to an apropriate zoom level when position changes
    [mapView setUserTrackingMode:MKUserTrackingModeFollow];

    //don't let the user drag around the the map -> just zooming enabled
    [mapView setScrollEnabled:NO];

    [self.view addSubview:mapView];
}

Then the app looks like this: App with TrackingMode App zoomed out in TrackingMode

For more information just read the Apple Documentation: http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MKMapView_Class/MKMapView/MKMapView.html

Upvotes: 0

Misha
Misha

Reputation: 5380

This shell do the trick: mkMapview.showsUserLocation = YES;

Upvotes: 0

Related Questions