Center MKMapView on userLocation (initially) - only works on iPhone 4?

geerlingguy picture geerlingguy · Feb 23, 2011 · Viewed 11.7k times · Source

I implemented the following MKMapView method, which runs after annotations are added. I have my MKMapView map (parishMap) set to "Shows user location" in Interface Builder, and upon loading the mapview, the blue dot always appears within a second or so on the mapview.

Here's the code I have in my Map View controller implementation:

// Center map on user location (initially)
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
    for(MKAnnotationView *annotationView in views) {
        if(annotationView.annotation == parishMap.userLocation) {
            MKCoordinateRegion region;
            MKCoordinateSpan span;

            span.latitudeDelta=0.03;
            span.longitudeDelta=0.03;

            CLLocationCoordinate2D location=parishMap.userLocation.coordinate;

            location = parishMap.userLocation.location.coordinate;

            region.span=span;
            region.center=location;

            [parishMap setRegion:region animated:TRUE];
            [parishMap regionThatFits:region];
        }
    }
}

When I open the mapview on my iPhone 4, the mapview always (and almost immediately) moves to center on the userLocation dot. However, when I open the mapview on an iPhone 3Gs or iPod Touch (2010), it doesn't center on the userLocation, but just stays at the default zoom/region I set for the map view.

Any ideas as to why this code won't work for non-iPhone 4 devices (they're all running 4.2.x latest iOS)?

Answer

Rog picture Rog · Feb 24, 2011

This is probably an issue with the amount of time it takes for the GPS to lock a position on these different devices.

I'd recommend using CLLocationManager and its delegate methods to center the map.

You can start updating location by creating an instance of CLLocationManager, setting its delegate property to self and then implementing:

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

Where you can center your map accordingly based on the latest location update.