How to delay callout from showing when annotation selected in MKMapView? Swift 4

630 Views Asked by At

(This is my first stack overflow question haha)

UPDATE: From this link - Center MKMapView BEFORE displaying callout

I implemented the solution from Thermometer, however selecting and deselecting the annotation makes it look like my application is glitching.

I think the best way would be to delay the callOut (detail pop up) from appearing by a few seconds so the map has time to move first.

Here is my code:

func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
    guard let annotation = view.annotation else {
        return
    }

    let currentAnnotation = view.annotation as? MapMarker
    Global.currentAnnotation = currentAnnotation
    findRelatinoshipLines()

    if Global.showLifeStoryLines {
        var locations = lifeStoryAnnotations.map { $0.coordinate }
        let polyline = MKPolyline(coordinates: &locations, count: locations.count)
        Global.finalLineColor = Global.lifeStoryColor
        mapView.addOverlay(polyline)
    }

    if Global.showFatherLines {
        var fatherLocations = fatherTreeAnnotations.map { $0.coordinate }
        let fatherPolyline = MKPolyline(coordinates: &fatherLocations, count: fatherLocations.count)
        Global.finalLineColor = Global.fatherLineageColor

        mapView.addOverlay(fatherPolyline)
    }

    if Global.showMotherLines {
        var motherLocations = motherTreeAnnotations.map { $0.coordinate }
        let motherPolyline = MKPolyline(coordinates: &motherLocations, count: motherLocations.count)
        Global.finalLineColor = Global.motherLineageColor

        mapView.addOverlay(motherPolyline)
    }

    if Global.showSpouseLines {
        var locations = spouseAnnotations.map { $0.coordinate }
        let polyline = MKPolyline(coordinates: &locations, count: locations.count)
        Global.finalLineColor = Global.spouseColor
        mapView.addOverlay(polyline)
    }

    if Global.zoomChange == true {
        Global.zoomChange = false
    } else {
        let currentRegion = mapView.region
        let span = currentRegion.span
        let location = currentAnnotation!.coordinate
        let region = MKCoordinateRegion(center: location, span: span)

        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
            mapView.setCenter(annotation.coordinate, animated: true)
            //mapView.setRegion(region, animated: true)
        }
    }
}

CONTINUED:

Basically I'm working on a family genealogy application that displays events from relatives on a map.

When I click an annotation (event) the details (who event belongs to, where and when, etc) pops up above with an information button to show the selected person.

I have it set up to set the MKMapView region so that the selected annotation is centered each time a new annotation is clicked.

The problem is when I click an event that is on the edge of the screen, my annotation title/description pops up off centered so that it fits on my screen because it doesn't know that I plan on re-centering the map view around said annotation.

I was wondering if there was any way to make the title/description appear centered directly above the selected annotation so that when I move the map everything is centered and fits on the screen.

Here are some screenshots of what I'm talking about:

Before and After

1

There are 1 best solutions below

2
On

Solved it by calling setCenter with a slight delay in mapView(_:didSelect:):

func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
    guard let annotation = view.annotation else {
        return
    }

    DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
        mapView.setCenter(annotation.coordinate, animated: true)
    }
}

enter image description here