Skip to content

Instantly share code, notes, and snippets.

@robertmryan
Last active June 15, 2024 01:45
Show Gist options
  • Save robertmryan/0bb16a0e5c2863234085c5ce3449550e to your computer and use it in GitHub Desktop.
Save robertmryan/0bb16a0e5c2863234085c5ce3449550e to your computer and use it in GitHub Desktop.
class PetAnnotation: MKPointAnnotation {
let type: PetType
init(_ type: PetType, title: String? = nil, subtitle: String? = nil, latitude: Double, longitude: Double) {
self.type = type
super.init()
self.title = title
self.subtitle = subtitle
self.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
}
enum PetType {
case dog
case cat
case budgie
}
}
class PetAnnotationView: MKMarkerAnnotationView {
override var annotation: (any MKAnnotation)? { didSet { update() } }
override init(annotation: (any MKAnnotation)?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
update()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
update()
}
}
private extension PetAnnotationView {
func update() {
guard let annotation = annotation as? PetAnnotation else {
glyphImage = nil
return
}
switch annotation.type {
case .dog: glyphImage = UIImage(systemName: "dog.fill")
case .cat: glyphImage = UIImage(systemName: "cat.fill")
case .budgie: glyphImage = UIImage(systemName: "bird.fill")
}
}
}
class ViewController: UIViewController {
@IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
mapView.register(PetAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
addAnnotations()
}
func addAnnotations() {
let locations = [
PetAnnotation(.dog, title: "New York, NY", latitude: 40.713054, longitude: -74.007228),
PetAnnotation(.cat, title: "Los Angeles, CA", latitude: 34.052238, longitude: -118.243344),
PetAnnotation(.budgie, title: "Chicago, IL", latitude: 41.883229, longitude: -87.632398)
]
mapView.addAnnotations(locations)
}
}
@robertmryan
Copy link
Author

Resulting in

Simulator Screenshot - iPhone 15 Pro Max - 2024-06-14 at 18 35 25

@robertmryan
Copy link
Author

Or you can do it on the basis of the annotation type:

class DogAnnotation: MKPointAnnotation {
    init(title: String? = nil, subtitle: String? = nil, latitude: Double, longitude: Double) {
        super.init()

        self.title = title
        self.subtitle = subtitle
        self.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
    }
}

class CatAnnotation: MKPointAnnotation {
    init(title: String? = nil, subtitle: String? = nil, latitude: Double, longitude: Double) {
        super.init()

        self.title = title
        self.subtitle = subtitle
        self.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
    }
}

class BudgieAnnotation: MKPointAnnotation {
    init(title: String? = nil, subtitle: String? = nil, latitude: Double, longitude: Double) {
        super.init()

        self.title = title
        self.subtitle = subtitle
        self.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
    }
}

class AnimalAnnotationView: MKMarkerAnnotationView {
    override var annotation: (any MKAnnotation)? { didSet { update() } }

    override init(annotation: (any MKAnnotation)?, reuseIdentifier: String?) {
        super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
        update()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        update()
    }
    
    func update() {
        glyphImage = switch annotation {
            case is DogAnnotation:    UIImage(systemName: "dog.fill")
            case is CatAnnotation:    UIImage(systemName: "cat.fill")
            case is BudgieAnnotation: UIImage(systemName: "bird.fill")
            default:                  nil
        }
    }
}

class ViewController: UIViewController {
    @IBOutlet weak var mapView: MKMapView!

    override func viewDidLoad() {
        super.viewDidLoad()
        mapView.register(AnimalAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
        addAnnotations()
    }

    func addAnnotations() {
        let locations = [
            DogAnnotation(title: "New York, NY",    latitude: 40.713054, longitude: -74.007228),
            CatAnnotation(title: "Los Angeles, CA", latitude: 34.052238, longitude: -118.243344),
            BudgieAnnotation(title: "Chicago, IL",  latitude: 41.883229, longitude: -87.632398)
        ]

        mapView.addAnnotations(locations)
    }
}

Same result.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment