iosswiftxcodemapkitmklocalsearch

Using MKLocalSearch in Swift attaches a pin to the users location instead of the blue dot


I am new to coding and Stack Overflow, so forgive me if I do something wrong.

I am using MKLocalSearch to display locations specified by a string. I have a user and location, so everything is setup.

I have added MKLocalSearch to my app, and it works correctly but now puts an MKPointAnnotation over the users' location. Of course, I want the famous blue dot to appear rather than an annotation.

I have already tried going over the code and to look up this issue but haven't had any luck finding a solution.

Here is my MKLocalSearch Code:

let request = MKLocalSearch.Request()
request.naturalLanguageQuery = "Dispensaries"
request.region = MapView.region

let search = MKLocalSearch(request: request)
search.start(completionHandler: {(response, error) in
    if error != nil {
        print("Error occured in search")
    } else if response!.mapItems.count == 0 {
        print("No matches found")
    } else {
        print("Matches found")

        for item in response!.mapItems {
            let annotation = MKPointAnnotation()
            annotation.title = item.name
            annotation.coordinate = item.placemark.coordinate
            DispatchQueue.main.async {
                self.MapView.addAnnotation(annotation)
            }
            print("Name = \(String(describing: item.name))")
            print("Phone = \(String(describing: item.phoneNumber))")
            print("Website = \(String(describing: item.url))")
        }
    }
})

Here is my viewForAnnotation

extension MapViewController: MKMapViewDelegate {
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        var view = mapView.dequeueReusableAnnotationView(withIdentifier: "reuseIdentifier") as? MKMarkerAnnotationView
        if view == nil {
            view = MKMarkerAnnotationView(annotation: nil, reuseIdentifier: "reuseIdentifier")`

            let identifier = "hold"

            var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)

            if annotationView == nil {
                annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: identifier)
                annotationView?.canShowCallout = true

                let btn = UIButton(type: .detailDisclosure)
                annotationView?.rightCalloutAccessoryView = btn
            } else {
                annotationView?.annotation = annotation
            }
        }

        view?.annotation = annotation
        view?.displayPriority = .required

        return view
    }
}

Solution

  • In func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) check the annotation type e.g.

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        if annotation is MKUserLocation { return nil }
    
        // the rest of your code
    }
    

    If you return nil from this method, the MKMapView uses its default built in annotation views, for MKPointAnnotation it uses the red pin, for MKUserLocation the blue dot you are looking for.