Mapkit Multiple Annotations - annotations

I'm having some problems with adding annotations, I'm currently making an app that displays all pizza places near your location. I know how to display the current location, but I need help with MapKit. I want to display the pizza places but I also want it to print the name and the phone number (in Xcode). What lines of code do I need to add?

How to add one map annotation:
let annotation = MKPointAnnotation()
annotation.coordinate = CLLocationCoordinate2D(latitude: 10.0, longitude: 59.0)
annotation.title = "Pizza Place"
annotation.subtitle = "Phone: 0012345678"
map.addAnnotation(annotation)
A function to add multiple Pizza Place annotations:
func addPizzaPlacesToMap(places: [PizzaPlace]) {
// Remove all annotations from map
self.map.removeAnnotations(self.map.annotations)
// Loop trough all your pizza places and add them to the map
for place in places {
let annotation = MKPointAnnotation()
annotation.title = place.name
annotation.subtitle = place.phone
annotation.coordinate = place.coordinate
self.map.addAnnotation(anno)
}
}

Related

MapKit, Set current location manually ? It is possible?

How to display current location from coordinates manually? I am taking coordinates from another GPS device. How to set it manually?
Where the coordinates come from is largely immaterial: as long as you have one you can set the map to display an area including that point. If you want to display the point itself you can add an annotation:
A simple example method to drop a pin and zoom in to its location:
func createAnnotation(from coordinate: CLLocationCoordinate2D, title: String) -> MKPointAnnotation {
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate
annotation.title = title
return annotation
}
func dropPinAndZoomIn(to coordinate: CLLocationCoordinate2D){
var spanDelta = 0.035 //the width/height of the map area in degrees
let annotation = createAnnotation(from: coordinate, title: "My Location")
mapView.removeAnnotations(mapView.annotations) //clear any prev annotations
mapView.addAnnotation(annotation)
let span = MKCoordinateSpan(latitudeDelta: spanDelta, longitudeDelta: spanDelta)
let region = MKCoordinateRegion(center: coordinate, span: span)
let displayRegion = mapView.regionThatFits(region) //ensure the region can be displayed in the mapView's view
mapView.setRegion(displayRegion, animated: true)
}

MKMapItem Center for creating annotations

I am trying to perform an MKLocalSearch.Request() and display the result on my mapView similar to this tutorial however when I do the search the coordinates returned are off center from where they should be. Where the map displays Brooklyn as an overlay in the center of the borough correctly the annotation is far off center to the left. I've noticed that there are two sets of coordinates contained in MKMapItem one the location and the other shown as center when printed to the console. I am not sure how to access the center coordinate but the center coordinate is the correct one in the middle of the screen. How can I access the center coordinate to use as the MKAnnotation's coordinate? Thank you
Search Code
let searchRequest = MKLocalSearch.Request()
searchRequest.naturalLanguageQuery = "brooklyn"
searchRequest.region = MKCoordinateRegion(center: CLLocationCoordinate2DMake(40.758896, -73.985130), latitudinalMeters: 2000, longitudinalMeters: 2000)
let search = MKLocalSearch(request: searchRequest)
search.start { (response, error) in
if let error = error{
print("Error performing search for location")
}
if let response = response{
for item in response.mapItems{
print("map item returned: \(item)")
print("latitude: \(item.placemark.coordinate.latitude) longitude: \(item.placemark.coordinate.longitude)")
let annotation = MKPointAnnotation()
annotation.coordinate = item.placemark.coordinate
annotation.title = item.name
self.mapView.addAnnotation(annotation)
}
}
}
Output
map item returned: Optional(CLCircularRegion (identifier:'<+40.64529796,-73.94483550> radius 14090.15', center:<+40.64529796,-73.94483550>, radius:14090.15m))
latitude: 40.6924599 longitude: -73.9903805
I was able to access the center by casting the region property of MKMapItem's placemark property from CLRegion to CLCircularRegion.
if let response = response{
for item in response.mapItems{
print("map item returned: \(item.placemark)")
if let region = item.placemark.region as? CLCircularRegion{
print("region.center: \(region.center)")
let annotation = MKPointAnnotation()
annotation.coordinate = region.center
annotation.title = item.name
self.mapView.addAnnotation(annotation)
}
}

annotation Display Priority doesn't do what I expect, how to keep custom pin on screen

I use the code below on view did load to add a custom annotation icon for the map center that the user started at so that if they scroll away they can always see their starting point.
if let lat = curBlip.blip_lat, let lon = curBlip.blip_lon {
let mapCenter = CLLocationCoordinate2DMake(lat, lon)
let mapSpan = MKCoordinateSpanMake(0.01, 0.01)
let mapRegion = MKCoordinateRegionMake(mapCenter, mapSpan)
self.map.setRegion(mapRegion, animated: true)
let coordinate = CLLocationCoordinate2D(latitude: lat, longitude: lon)
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate
annotation.title = "Your Blips Location"
annotation.subtitle = "Subtitle Placeholder"
self.map.addAnnotation(annotation)
When the view loads I load that annotation so its always first and I set a bool named "set" to true after the first annotation to ensure that it gets the custom icon. The issue I am having is that even though I have the annotation set to display priority required the annotation disappears when I move the map away. How can I make that annotation always persist or is there a better way to set a "this is where the map started" circle that doesn't go away?
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if set {
return nil
} else {
let view = MKAnnotationView(annotation: annotation, reuseIdentifier: "annotationId")
view.image = UIImage(named: "locationArea50")
view.canShowCallout = true
view.displayPriority = .required
set = true
return view
}
Then after I scroll the map away a little bit, I suspect scrolling far enough that the system has to make them reappear the annotation disappears. I assume this has to do with how the grouping of annotations works but that blue annotation is special and I want it to always be present, which is what I thought displayPriority did.
The default value of displayPriority is .required .
So for correct overlapping you need to downgrade priority of red annotations:
redAnnotation.displayPriority = .defaultHigh

Add Annotations in MapKit - Programmatically

I am trying to add annotations to my map.
I have an array of points with coordinates inside.
I am trying to add annotations from those coordinates.
I have this defined:
var points: [CLLocationCoordinate2D] = [CLLocationCoordinate2D]()
let annotation = MKPointAnnotation()
points has coordinates inside. I checked. And I do this:
for index in 0...points.count-1 {
annotation.coordinate = points[index]
annotation.title = "Point \(index+1)"
map.addAnnotation(annotation)
}
It keeps adding only the last annotation... Instead of all of them.
Why is this?
By the way, is there a way to delete a specified annotation, by title for example?
Each annotation needs to be a new instance, you are using only one instance and overriding its coordinates. So change your code:
for index in 0...points.count-1 {
let annotation = MKPointAnnotation() // <-- new instance here
annotation.coordinate = points[index]
annotation.title = "Point \(index+1)"
map.addAnnotation(annotation)
}
You can edit your for loop with the below code
I think your array would be like points array
let points = [
["title": "New York, NY", "latitude": 40.713054, "longitude": -74.007228],
["title": "Los Angeles, CA", "latitude": 34.052238, "longitude": -118.243344],
["title": "Chicago, IL", "latitude": 41.883229, "longitude": -87.632398]
]
for point in points {
let annotation = MKPointAnnotation()
annotation.title = point["title"] as? String
annotation.coordinate = CLLocationCoordinate2D(latitude: point["latitude"] as! Double, longitude: point["longitude"] as! Double)
mapView.addAnnotation(annotation)
}
it's working for me. All the best for you.

MKLaunchOptionsMapSpanKey & Apple MapKit

What is the correct way to auto zoom an iOS MapKit MKMapItem generated map when it first displays using the option MKLaunchOptionsMapSpanKey:?
Specifically, how should the zoom factor be entered for MKLaunchOptionsMapSpanKey:??? (i.e. MKLaunchOptionsMapSpanKey:0.1).
Or, alternatively, is there another way programmatically to auto zoom the map when it first displays which I am not aware of?
#IBAction func getDirections(sender: AnyObject) {
let mapItem = MKMapItem.mapItemForCurrentLocation()
let coords = CLLocationCoordinate2DMake(latitude, longitude)
mapItem.name = "User Location"
let options = [MKLaunchOptionsMapSpanKey:???,MKLaunchOptionsMapCenterKey:location, ]
let place = MKPlacemark(coordinate: coords, addressDictionary:nil)
mapItem.openInMapsWithLaunchOptions(options)
}