Center maps in iOS Programming

◇◆丶佛笑我妖孽 提交于 2019-12-04 06:16:21

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:

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

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

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:

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

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!