How to get rid of the MKBalloonCalloutView in iOS 14

130 Views Asked by At

I have the following code which works for iOS 13 and lower.

func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
    mapView.userLocation.title = "You are here"
    mapView.userLocation.subtitle = // user's location
}

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

    if annotation.isKind(of: MKUserLocation.self) {
        return nil
    }
}

It shows only the blue dot without a callout and above the blue dot is just the title and subtitle.

enter image description here

But on iOS 14 there is a default MKBalloonCalloutView that appears in place of the title and subtitle. It shows a gray profileImage. How can I get rid of the BalloonCallout so I can show just the title and subtitle?

enter image description here

enter image description here

2

There are 2 best solutions below

1
On

By setting your own detail detailCalloutAccessoryView for the User Location annotation's MKAnnotationView the behaviour reverts to just showing title and subtitle.

You can set any UIView of your choice, like an UIImageView for example, or just an empty one.

For example in your MKMapViewDelegate

func mapViewDidFinishLoadingMap(_ mapView: MKMapView) {
    mapView.view(for: mapView.userLocation)?.detailCalloutAccessoryView = .init()
}
0
On

For the user (the one from the question), if using iOS 14 and higher I use MKMarkerAnnotationView,. If using iOS 13 or lower I use MKPinAnnotationView. I have a separate custom pin for everyone else:

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

    let reuseIdentifier = "MyIdentifier"

    if annotation.isKind(of: MKUserLocation.self) {

        if #available(iOS 14.0, *) {
            if let pin = mapView.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier) as? MKMarkerAnnotationView {
                
                return setMKMarkerAnnotationView(pin: pin)
            }
        } else {
            let pin = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
            pin.canShowCallout = true
            return pin
        }
        return nil

    } else {

        // dequeue the custom pins for everyone else
    }
}

func setMKMarkerAnnotationView(pin: MKMarkerAnnotationView) -> MKMarkerAnnotationView {
    
    pin.animatesWhenAdded = true
    
    pin.markerTintColor = UIColor.red
    pin.titleVisibility = .visible
    pin.subtitleVisibility = .visible
    
    return pin
}