Now that we know how to read a location from our device, here’s how to display that location in a Map View. All we need is a referenced MKMapView in your storyboard, and to import the MapKit framework into our project / class.
For the map view to display our coordinates, we need to create an MKCoordinateRegion and give it those coordinates. We can optionally pass Delta values for longitude and latitude which will specify how zoomed in the map view will appear. Smaller values are closer, larger values are further away from our region.
This method takes a CLLocation from our previous step and sets them in our map view:
1 2 3 4 5 6 7 8 9 10 11 |
- (void)updateMapView:(CLLocation *)location { // create a region and pass it to the Map View MKCoordinateRegion region; region.center.latitude = location.coordinate.latitude; region.center.longitude = location.coordinate.longitude; region.span.latitudeDelta = 0.001; region.span.longitudeDelta = 0.001; [self.mapView setRegion:region animated:YES]; } |
Setting a Pin on the centre
Notice how the above displays the map correctly, but no red centre pin. To do that we need to create an MKPlacemark with the same longitude and latitude as above:
[emember_protected]
1 2 3 4 5 6 7 |
// remove previous marker MKPlacemark *previousMarker = [self.mapView.annotations lastObject]; [self.mapView removeAnnotation:previousMarker]; // create a new marker in the middle MKPlacemark *marker = [[MKPlacemark alloc]initWithCoordinate:location.coordinate addressDictionary:nil]; [self.mapView addAnnotation:marker]; |
While updating our map view with a new location, we can create a trail of markers for “the journey taken”. If you don’t want that you need to remove a marker first before placing another one. You can add as many markers as you like.
Displaying the address of the current location
Another nice touch is to display where exactly the location is, as in which street number, county, ZIP code and so forth. For that we can use the CLGeocoder class. This puppy can turn an address into location coordinates, or turn coordinates into a human readable location.
Here’s how we can do the latter:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// create an address from our coordinates CLGeocoder *geocoder = [[CLGeocoder alloc]init]; [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) { CLPlacemark *placemark = [placemarks lastObject]; NSString *address = [NSString stringWithFormat:@"%@, %@, %@, %@", placemark.thoroughfare, placemark.locality, placemark.administrativeArea, placemark.postalCode]; if (placemark.thoroughfare != NULL) { self.addressLabel.text = address; } else { self.addressLabel.text = @""; } }]; |
[/emember_protected]
This method is called asynchronously and hence uses a block which is called upon completion. In it we’ll access the place marks array and grab the last object, then access its many exciting properties. Note that sometimes that information is not available, hence I’m querying the first one before updating a label (which would show NULL if no information is present).
I’ve created a Demo Project on GitHub called Locations – feel free to fork and examine how it works.
- https://github.com/versluis/Locations
- https://developer.apple.com/library/ios/documentation/MapKit/Reference/MKMapView_Class/MKMapView/MKMapView.html#//apple_ref/doc/uid/TP40008205
- https://developer.apple.com/library/ios/documentation/MapKit/Reference/MKPlacemark_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40008322