skip to Main Content

I am creating an app to show user locations on a single MapView. Within the app, the user is able to place down an annotation by tapping the screen. This annotation is called my CustomAnnotation for plotting a route from their location, to that dropped pin. Now, I have created another annotation class called MemberAnnotation. I created a pop-up button that will allow the user to choose how they want their annotation color to look. I have already created an extension on UIColor to convert a UIColor’s RGB values into a string, save that string to FireBase, and convert the string back into a UIColor when fetched. Now, I just can’t seem to figure out how to customize each annotation for the specified member.

I have created a function to customize the routing pin:

func setupCustomAnnotations(for annotation: CustomAnnotation, on mapView: MKMapView) -> MKAnnotationView? {
    annotation.title = "Route"
    
    let view = mapView.dequeueReusableAnnotationView(withIdentifier: self.routeIdentifier, for: annotation)
    if let markerAnnotationView = view as? MKMarkerAnnotationView {
        markerAnnotationView.animatesWhenAdded = true
        markerAnnotationView.canShowCallout = true
        markerAnnotationView.markerTintColor = UIColor.black
        btn.setImage(UIImage(systemName: "location"), for: .normal)
        markerAnnotationView.leftCalloutAccessoryView = btn
    }
    return view
}

And I am calling it in my MapView Delegate:

extension MapHomeViewController: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    guard !annotation.isKind(of: MKUserLocation.self) else { return nil }
    var annotationView: MKAnnotationView?
    
    if let annotation = annotation as? CustomAnnotation {
         annotationView = setupCustomAnnotations(for: annotation, on: mapView)
    }
    return annotationView
}

Just not sure what to include in the separate function, where to call, or if I even need to make a separate one? Any step in the right direction would be a massive help, thank you!

2

Answers


  1. Chosen as BEST ANSWER

    I ended up getting it shortly after making this post but forgot to post my answer! Here is the following code I wrote on the MKMapViewDelegate extension:

        func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        var annotationView: MKAnnotationView?
        
        if let annotation = annotation as? CustomAnnotation {
            annotationView = mapHomeViewModel.setupCustomAnnotations(for: annotation, on: mapView)
            return annotationView
        } else if let annotation = annotation as? MemberAnnotation {
            annotationView = mapHomeViewModel.setupMemberAnnotations(for: annotation, on: mapView)
            return annotationView
        }
        return nil
    }
    

    And here are the 2 functions that I created on my ViewModel:

        func setupMemberAnnotations(for annotation: MemberAnnotation, on mapView: MKMapView) -> MKAnnotationView? {
        annotation.title = annotation.member.screenName
        
        let view = mapView.dequeueReusableAnnotationView(withIdentifier: "Member", for: annotation)
        guard let markerColor = String.convertToColorFromString(string: annotation.member.mapMarkerColor) else { return nil }
        if let markerAnnotationView = view as? MKMarkerAnnotationView {
            markerAnnotationView.animatesWhenAdded = true
            markerAnnotationView.canShowCallout = false
            markerAnnotationView.markerTintColor = markerColor
        }
        return view
    }
    
    func setupCustomAnnotations(for annotation: CustomAnnotation, on mapView: MKMapView) -> MKAnnotationView? {
        annotation.title = "Route"
        
        let view = mapView.dequeueReusableAnnotationView(withIdentifier: "Route", for: annotation)
        if let markerAnnotationView = view as? MKMarkerAnnotationView {
            markerAnnotationView.animatesWhenAdded = true
            markerAnnotationView.canShowCallout = true
            markerAnnotationView.markerTintColor = UIColor.black
            btn.setImage(UIImage(systemName: "location"), for: .normal)
            markerAnnotationView.leftCalloutAccessoryView = btn
        }
        return view
    }
    

    Hopefully this helps someone out later on!


  2. Here is my quick solution, hope that it will help you.

    import MapKit
    
    class CustomAnnotation: NSObject, MKAnnotation {
        
        let userID: String
        // Or u can use Integer as ID if u want.
        let colorToDisplay: UIColor
        
        // MKAnnotation required declaration
        var title: String?
        let subtitle: String?
        let coordinate: CLLocationCoordinate2D
        
        init(userID: String, colorToDisplay: UIColor, title: String?, subtitle: String?, coordinate: CLLocationCoordinate2D) {
            self.userID = userID
            self.colorToDisplay = colorToDisplay
            self.title = title
            self.subtitle = subtitle
            self.coordinate = coordinate
        }
    }
    
    // In the function that u create CustomAnnotaion instance
    let anno = CustomAnnotation.init(userID: "ABCD1234", colorToDisplay: "Your converted color from HEX here", title: "your title", subtitle: "your subtitle", coordinate: yourCoordinate)
    
    func setupCustomAnnotations(for annotation: CustomAnnotation, on mapView: MKMapView) -> MKAnnotationView? {
        annotation.title = "Route"
        
        // Now get the corresponding user data here, by searching by userID, that we saved in CustomAnnotation before.
        let toSearchUserID = annotation.userID // ABCD1234
        let userData = yourListUser.filter { $0.userID == userID }
    
        let view = mapView.dequeueReusableAnnotationView(withIdentifier: self.routeIdentifier, for: annotation)
        if let markerAnnotationView = view as? MKMarkerAnnotationView {
            markerAnnotationView.animatesWhenAdded = true
            markerAnnotationView.canShowCallout = true
            markerAnnotationView.markerTintColor = UIColor.black
            btn.setImage(UIImage(systemName: "location"), for: .normal)
            markerAnnotationView.leftCalloutAccessoryView = btn
        }
        return view
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search