Rather than implementing mapView(_:didAdd:)
in the MKMapViewDelegate
, you can also have the annotation view do the animation itself.
class CustomAnnotationView: MKAnnotationView {
override var annotation: MKAnnotation? { didSet { update(for: annotation) } }
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
update(for: annotation)
}
override func prepareForReuse() {
super.prepareForReuse()
removeFromSuperview()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func didMoveToSuperview() {
super.didMoveToSuperview()
transform = CGAffineTransform(translationX: 0, y: -100)
alpha = 0
UIViewPropertyAnimator(duration: 0.5, dampingRatio: 0.4) {
self.transform = .identity
self.alpha = 1
}.startAnimation()
}
private func update(for annotation: MKAnnotation?) {
// do whatever update to the annotation view you want, if any
}
}
This is useful for avoiding the cluttering of one’s view controller with annotation view animations. E.g. in iOS 11 and later, you might do:
mapView.register(CustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
And then you can add an annotation to your map view, and you get this animation of the annotation view without any more code in the view controller.
This particular animation is a drop with a little bounce at the end, but obviously you can do whatever animation you want.
The above was written in Swift, but the concept is equally valid in Objective-C, too.