I looked at the posts for this and I still do not receive a custom pin....
Custom Annotation --> this includes setting my image
import UIKit
import MapKit
class CustomPointAnnotation: MKPointAnnotation {
var pinCustomImageName: UIImage!
}
View Controller:
I want to return current location until a button is selected to drop pin
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
//current Location
if !(annotation is CustomPointAnnotation) {
return nil
}
let reuseIdentifier = "pin"
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier)
if annotationView == nil {
annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
annotationView!.canShowCallout = true
} else {
annotationView!.annotation = annotation
}
if let annotationView = annotationView {
annotationView.image = UIImage(named: "Skyscraper")
annotationView.canShowCallout = true
}
return annotationView
}
func addPin() {
pointAnnotation = CustomPointAnnotation()
pointAnnotation.pinCustomImageName = UIImage(named: "Skyscraper")
pointAnnotation.coordinate = currentLocation.coordinate
pointAnnotation.title = "First Building"
pointAnnotation.subtitle = "Latitude: \(currentLocation.coordinate.latitude), \
(currentLocation.coordinate.longitude)"
mapView.addAnnotation(pointAnnotation)
}
There's nothing seriously wrong with the code. But there can be a couple of things that would cause problems, including:
Have you set the delegate
(either in IB or programmatically) for the map view? If not, your mapView(_:viewFor:)
will never be called. Add breakpoint or debugging print
statement to confirm.
Have you confirmed that UIImage(named: "Skyscraper")
is successfully retrieving an image? Make sure this is not returning nil
.
Note, if only iOS 11 and later, you can simplify this code a bit. Since iOS 11, we no longer need for mapView(_:viewFor:)
in simple scenarios like this. I would suggest putting the annotation view configuration code within the annotation view subclass, where it belongs, and avoid cluttering our view controller with a viewFor
implementation.
So when you do get the current issue behind you, the recommended process is:
Define classes for your annotation and annotation view:
class CustomAnnotation: MKPointAnnotation {
var pinCustomImage: UIImage!
}
And
class CustomAnnotationView: MKAnnotationView {
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
canShowCallout = true
update(for: annotation)
}
override var annotation: MKAnnotation? { didSet { update(for: annotation) } }
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func update(for annotation: MKAnnotation?) {
image = (annotation as? CustomAnnotation)?.pinCustomImage
}
}
In viewDidLoad
register this annotation view class:
mapView.register(CustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
Remove mapView(_:viewFor:)
implementation.
Now when you add a CustomAnnotation
to your map’s list of annotations, it will be rendered correctly.
But I would suggest resolving your current problem first. There’s no point in refining you implementation until these more basic issues are resolved.