Reputation: 1
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!
Upvotes: 0
Views: 120
Reputation: 1
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!
Upvotes: 0
Reputation: 542
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
}
Upvotes: 0