The idea is simple. I have an array of StopData() which a custom struct I created to display different locations a mapView by doing a for each loop. My code looks a little like this:
var route = [StopData]()
struct StopData {
var addr: String?
var coord: CLLocationCoordinate2D?
var number: Int?
var completed = false
}
func addStopsToMap() {
mapView.removeAnnotations(mapView.annotations)
for stop in route {
let annotation = MKPointAnnotation()
annotation.coordinate = stop.coord!
annotation.title = "\(stop.number!)"
annotation.subtitle = stop.addr
mapView.addAnnotation(annotation)
}
}
func attemptLocationAccess() {
// For use in foreground
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
return NonClusteringAnnotation(annotation: annotation, reuseIdentifier: "NonClusteringAnnotation")
}
// MARK: - Location manager functions
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
return
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
locationManager.requestWhenInUseAuthorization()
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
guard status == .authorizedWhenInUse else {
return
}
manager.requestLocation()
}
I also have a custom class like the following:
class NonClusteringAnnotation: MKMarkerAnnotationView {
override var annotation: MKAnnotation? {
willSet {
displayPriority = .required
}
}
}
I have three main things I would like to accomplish.
- Show every annotation pin and not have it cluster
- Show custom annotation if the variable completed is false
- Show a different custom annotation if completed is true
With this code, every pin is shown on the map and does not cluster. However, that also includes the current location blue dot which appears as a red pin like the rest of all the annotations. So I was wondering how can I make multiple custom annotation views and assign them only certain annotations whilst still retaining the blue dot indicating the users current location?
What I tried so far is adding a Boolean variable like willUseCustomAnnotation which would trigger a different return value like this:
func addStopsToMap() {
mapView.removeAnnotations(mapView.annotations)
willUseCustomAnnotation = true
for stop in route {
let annotation = MKPointAnnotation()
annotation.coordinate = stop.coord!
annotation.title = "\(stop.number!)"
annotation.subtitle = stop.addr
mapView.addAnnotation(annotation)
}
willUseCustomAnnotation = false
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if willUseCustomAnnotation {
return NonClusteringAnnotation(annotation: annotation, reuseIdentifier: "NonClusteringAnnotation")
} else {
return nil
}
}
This does not work though because I presume it first adds all the annotations to mapview and then creates the view for them all at once.
I read on forums to change the view for the annotation you must create your own view in the viewForAnnotation function however that is only if you want a single custom view and not multiple custom view like I want. I'm new to MapKit so help will be really appreciated.