In my code I am using Apple maps and correctly setting up a mapView and the delegate to self within a View Controller.
Within my ViewController I also have the following code within a for loop:
if userOnMapAlready == false {
let annotation = MKPointAnnotation()
annotation.coordinate = CLLocationCoordinate2D(latitude: otherUserLocation.coordinate.latitude, longitude: otherUserLocation.coordinate.longitude)
annotation.subtitle = otherUserUUID
self.mapView.addAnnotation(annotation)
}
I also have the following delegate function in my view controller, and again am setting mapview.delegate = self within the View Controller:
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
//return nil so map view draws "blue dot" for standard user location
return nil
}
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
pinView!.animatesDrop = true
pinView!.pinColor = .purple
}
else {
pinView!.annotation = annotation
}
return pinView
}
Sadly when the pins are drawn they are all red, not purple like the viewForAnnotation would suggest they should be. What is the problem?! Is it something to do with the reuseId not matching the unique subtitle im a assigning to each MKPointAnnotation??
UPDATE: just realized that the delegate function viewForAnnotation is never being called - which would explain why the pins are not purple. Why would viewForAnnotation not be getting called???
In the latest version of Swift the property would be:
pinView!.pinTintColor = .purple
or...
pinView!.pinTintColor = MKPinAnnotationView.purplePinColor()
↳ https://developer.apple.com/reference/mapkit/mkpinannotationview
Related
For some reason ever since I updated to iOS 11, my callout Accessory isn't being displayed for my annotations. I have a title and subtitle set up from data I query from my server, however I can't get the callout accessory along with the .detailedDisclosure to display.
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
print("viewForannotation")
if annotation is MKUserLocation {
//return nil
return nil
}
// guard let annotation = annotation as? CalloutPin else { return nil }
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKPinAnnotationView
if pinView == nil {
//print("Pinview was nil")
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
pinView!.animatesDrop = true
}
let button = UIButton(type: UIButtonType.detailDisclosure) as UIButton // button with info sign in it
pinView!.canShowCallout = true
pinView!.rightCalloutAccessoryView = button
// pinView?.detailCalloutAccessoryView = button
return pinView
}
Does anyone have a solution for this? Any help would be much appreciated as I've been dealing with this problem for a long time now as I need the callout Accessory to display in order for me to segue to another view controller when my annotation pin is selected. Thanks!
Here's what's being displayed right now: MapView Annotation
I have a mapView with annotations displaying titles and subtitles. The subtitles are sometimes longer than the width of the annotation, so I am wondering if i can make them multiline?
It's coded like this so far:
func annotate(newCoordinate, title: String, subtitle: String) {
let annotation = MKPointAnnotation()
annotation.coordinate = newCoordinate
annotation.title = title
annotation.subtitle = subtitle
self.map.addAnnotation(annotation)
}
Then i have a few options set in
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {...}
which are not relevant here.
Is it posible to make a custom annotation view?
I've tried a couple of things, but nothing worked. The closest I can get is adding a button to display the longer subtitle separately, but i'd rather have it inside the annotation.
Is it possible?
I figured it out, I added a label in viewForAnnotation and it just worked
¯\_(ツ)_/¯
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
//return nil so map view draws "blue dot" for standard user location
return nil
}
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
}
else {
pinView!.annotation = annotation
}
//THIS IS THE GOOD BIT
let subtitleView = UILabel()
subtitleView.font = subtitleView.font.fontWithSize(12)
subtitleView.numberOfLines = 0
subtitleView.text = annotation.subtitle!
pinView!.detailCalloutAccessoryView = subtitleView
return pinView
}
I want to change the colour of pin. Following is my code to add the pin on map. Thanks in advance. Any kind of help will be appreciated:
map.AddAnnotations(new MKPointAnnotation
{
Title = "Technician's Location",
Coordinate = new CLLocationCoordinate2D(lattitude, longitude)
});
You can use the pinColor property of MKPinAnnotationView.
This can be added in the delegate method func mapView(mapView: MKMapView!,
viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView!
A typical example of what this method can hold is :-
if annotation is MKUserLocation {
return nil
}
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.animatesDrop = true
pinView!.pinColor = .Purple // you can change color here!
}
else {
pinView!.annotation = annotation
}
return pinView
I am using MKPinAnnotationView inside my App.
I am setting MapView object as delegate, and using this code for customising my AnnotationView
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
//return nil so map view draws "blue dot" for standard user location
return nil
}
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
// pinView!.canShowCallout = true
pinView!.image = UIImage(named:"store.jpg")
pinView!.animatesDrop = true
pinView!.pinTintColor = UIColor.darkGrayColor()
}
else {
pinView!.annotation = annotation
}
return pinView
}
I am getting custom AnnotationView as I required.However, I am missing the features of title and subtitle of MKPointAnnotation.
I wish to see title and subtitle for the grey dots.
I was overriding one func
func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
mapView.deselectAnnotation(view.annotation, animated: true)
}
I commented this function out and got the titles and subtitles.
Updated Code
/*
func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
mapView.deselectAnnotation(view.annotation, animated: true)
}
*/
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
//return nil so map view draws "blue dot" for standard user location
return nil
}
let reuseId = "pin"
let pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView.canShowCallout = true
pinView.animatesDrop = true
pinView.pinTintColor = UIColor.darkGrayColor()
pinView.draggable = true
pinView.accessibilityLabel = "hello"
let btn = UIButton(type: .DetailDisclosure)
pinView.rightCalloutAccessoryView = btn
return pinView
}
I'm trying to change my pin annotation image to something other than the pin.
func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
if annotation is MKUserLocation {
//return nil so map view draws "blue dot" for standard user location
return nil
}
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
pinView!.animatesDrop = true
pinView!.pinColor = .Green
pinView!.image = UIImage(named: "icon1.png")
// Add image to left callout
var mugIconView = UIImageView(image: UIImage(named: "test.png"))
pinView!.leftCalloutAccessoryView = mugIconView
// Add detail button to right callout
var calloutButton = UIButton.buttonWithType(.DetailDisclosure) as UIButton
pinView!.rightCalloutAccessoryView = calloutButton
}
else {
pinView!.annotation = annotation
}
return pinView
Everything works except changing the pin image. I have a custom point annotation subclass which is this
I've been searching for hours but every other SO question I've found hasn't helped. I'd appreciate any help... thanks.
UPDATED WITH ANSWER
func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
if annotation is MKUserLocation {
//return nil so map view draws "blue dot" for standard user location
return nil
}
var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier("pin")
if pinView == nil {
pinView = MKAnnotationView(annotation: annotation, reuseIdentifier: "pin")
pinView!.canShowCallout = true
pinView!.image = UIImage(named: "test.png")
// Add image to left callout
var mugIconView = UIImageView(image: UIImage(named: "test.png"))
pinView!.leftCalloutAccessoryView = mugIconView
// Add detail button to right callout
var calloutButton = UIButton.buttonWithType(.DetailDisclosure) as UIButton
pinView!.rightCalloutAccessoryView = calloutButton
}
else {
pinView!.annotation = annotation
}
return pinView
}
You want MKAnnotationView, not MKPinAnnotationView. Pin annotations can't customize their image.
See this SO answer for additional details