-
Notifications
You must be signed in to change notification settings - Fork 472
Using MapKit
MapKit lets you use native maps in your app and overlay custom pins and annotations, including the user's location. It is generally the best way to visualize location information your app.
This page covers the most common topics for MapKit. By the end of it, you will understand how to accomplish the following:
- Center map over a point
- Drop pins at locations
- Use custom images for map pins – aka "custom annotations"
- Detect pin taps
- Show the user their location
- Send the user to get directions to pins
A MapKit map with custom images on pin annotations
You will need to add MapKit.framework
to your project first. You can find out how by reading our guide on Project Frameworks.
Be sure you import MapKit
into whatever view controllers will need to use maps.
- You can drag a
MapKit View
from Interface Builder's Object Library onto your Storyboard, and configure it just like a regular view.
Here are the configuration options for MKMapView
in the "DJ tab" (shown above):
- Type – Choose from Satellite vs Standard vs Hybrid Map types
- Allows – Disable Zooming, Rotating, and Scrolling to prevent the Map from moving, while still allowing interaction with any pins present
- Shows, Buildings and Annotations – toggle to let Apple's default points of interest show when available
- Shows, User Location – Show's user their location, when they're on Map. Using this first requires the user's permission for their location, by getting it through the
CoreLocation.framework
- 99.8% of the time after creating adding a Map View in interface builder, you'll want to create an outlet for it in your view controller.
import UIKit
import MapKit
class MapViewController: UIViewController{
var mapView: MKMapView!
...
You can set the Map's region whenever you want. In viewDidLoad
use animated: false
, if the map is on screen, you should use animated: true
.
override func viewDidLoad() {
super.viewDidLoad()
mapView.setRegion(MKCoordinateRegionMake(CLLocationCoordinate2DMake(37.783333, -122.416667), MKCoordinateSpanMake(0.1, 0.1)), animated: false)
//one degree of latitude is approximately 111 kilometers (69 miles) at all times.
}
Pins are the result of adding MKPointAnnotation
s to your view.
func addPin() {
let annotation = MKPointAnnotation()
var locationCoordinate = CLLocationCoordinate2DMake(37.783333, -122.416667)
annotation.coordinate = locationCoordinate
annotation.title = "Picture!"
mapView.addAnnotation(annotation)
}
When you add a annotation.title
, by default the system will display a "callout" when tapped. You can find out how to disable canShowCallout
in Use custom images for map pins.
You can trigger any action when a user taps on your pin.
- First you will need to become the delegate of
mapView
.
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
}
- Then you'll need to add a function, letting you know that your annotation was tapped.
func mapView(mapView: MKMapView!, didSelectAnnotationView view: MKAnnotationView!) {
UIAlertView(title: "tapped pin!", message: view.annotation.title, delegate: nil, cancelButtonTitle: "OK").show()
}
- Set
mapView.delegate = self
as you done in Detect pin taps. - Implement the following function in your view controller,
annotationView.image = thumbnailImage
is your time to shine by choosing the right thumbnailImage
func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
let reuseID = "myAnnotationView"
var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseID)
if (annotationView == nil) {
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseID)
annotationView.canShowCallout = true //set false to disable MKMapView's automatic pop-up with title
}
var thumbnailImage = getOurThumbnailForAnnotation(annotation)
annotationView.image = thumbnailImage
return annotationView
}
Note: The annotationView
's image will be displayed at full-size. No resizing is possible on the Map itself. For image resizing, see the FAQ at the bottom of this page.
var imageAnnotationDictionary : Dictionary = {}
func getOurThumbnailForAnnotation(annotation : MKAnnotation){
}
func addPinWithImage(image: UIImage) {
let annotation = MKPointAnnotation()
var locationCoordinate = CLLocationCoordinate2DMake(37.783333, -122.416667)
annotation.coordinate = locationCoordinate
mapView.addAnnotation(annotation)
}
In order to show the user their location, first we will need to request permission to use their location.
-
import CoreLocation
theCoreLocation.framework
, as referenced by Project Frameworks. Ask the user for permission to use their location.
A: As with many things, Google is the answer– Coordinates of San Francisco
- If the first number is South, use the negative
Latitude
inCLLocationCoordinate2DMake(latitude: -1.0 * Google's Latitude , longitude: Google's Longitude)
- If the second number is West, use a negative
Longitude
inCLLocationCoordinate2DMake(latitude: Google's Latitude , longitude: -1.0 * Google's Longitude)
You can also use this coordinate conversion service.
A: Here's a snippet for resizing a UIImage for MKAnnotationView's image property:
var resizeRenderImageView = UIImageView(frame: CGRectMake(0, 0, 45, 45))
resizeRenderImageView.layer.borderColor = UIColor.whiteColor().CGColor
resizeRenderImageView.layer.borderWidth = 3.0
resizeRenderImageView.contentMode = UIViewContentMode.ScaleAspectFill
resizeRenderImageView.image = fullSizeImage as! UIImage
UIGraphicsBeginImageContextWithOptions(resizeRenderImageView.frame.size, false, 0.0)
resizeRenderImageView.layer.renderInContext(UIGraphicsGetCurrentContext())
var thumbnail = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
We've also added a 3 pixel white border, in good taste.
TODO: Foursquare API can help you place items on the Map