How to change markerTintColor of specific annotationView in swift4 - swift

I created a property list for location details, title, subtitle ,type and coordinates. What I am trying to do is change the annotationView color according to the type of the location.In my code the compiler move directly to else statement. Could someone explain how can I solve this?
func readRecordFromPlist(){
//read record from plist code
}
func mapView(_ MapView: MKMapView, viewFor annotation: MKAnnotation) ->
MKAnnotationView? {
let obj = userNSObj()
if obj.type == "Type1" {
let view = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: "pin")
view.markerTintColor = .blue
return view
}else{
let view = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: "pin")
view.markerTintColor = .purple
return view
}
}

Related

Annotation Title in MapKit is not visible anymore

I uploaded an App to the AppStore on Monday. Everything worked fine. Since Thursday the Title of added Annotation is not visible anymore.
The App has an array of some Point of Interests. Each has a title and the coordinates. The PoI are showing and i can filter them for the title.
But the title is not visible.
I just fix it by adding the following function. Unfortunately it shows the title only by tabbing the pin.
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
guard annotation is MKPointAnnotation else { return nil }
let identifier = "Annotation"
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
if annotationView == nil {
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView!.canShowCallout = true
} else {
annotationView!.annotation = annotation
}
return annotationView
}

Can't change the color: Value of type 'MKAnnotationView' has no member 'pinTintColor'

I'm trying to change to pin color on my map but I can't figure out how to do that using the class MKAnnotationView. I have seen a question here that is identical to this one but it hasn't been answered properly (i.e. the suggested answer does not work). Here's my code:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let identifier = "Placemark"
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
if annotationView == nil{
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView?.canShowCallout = true
annotationView?.pinTintColor = .green // throws an error (Value of type 'MKAnnotationView' has no member 'pinTintColor') !!
annotationView?.leftCalloutAccessoryView = UIButton(type: .detailDisclosure)
}else{
annotationView?.annotation = annotation
}
return annotationView
}
what am I doing wrong, and how do I fix it?
Could be that your annotationView is inferred to be a MKAnnotationView and not a MKPinAnnotationView. You could try like this instead.
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let identifier = "Placemark"
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
if annotationView == nil{
let newAnnotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
newAnnotationView.canShowCallout = true
newAnnotationView.pinTintColor = .green
newAnnotationView.leftCalloutAccessoryView = UIButton(type: .detailDisclosure)
return newAnnotationView
} else {
annotationView?.annotation = annotation
}
return annotationView
}

Trigger NavigationLink through tap on Annotation in Mapkit

I would like to trigger a NavigationLink through a tap on a Annotation in Mapkit. I am able to set a bool, that a certain annotation was tapped, but i never was able to call a SwiftUI View through it.
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
guard !(annotation is MKUserLocation) else {
return nil
}
let identifier = "Annotation"
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
if annotationView == nil {
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView?.canShowCallout = true
annotationView?.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
} else {
annotationView?.annotation = annotation
}
return annotationView
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
let selectedAssistance = self.parent.assistances.first {
$0.location.location?.coordinate == view.annotation?.coordinate
}
guard selectedAssistance != nil else {
return
}
self.parent.selectedAssistance = selectedAssistance?.serverId ?? ""
self.parent.presentSheet = true
}
I made it, by calling my own MapView in a ZStack, and placed a NavLink behind it, which is active on a Binding

How to use standard MKAnnotation Symbol with a custom made MKAnnotationView

I customized my callOutView, creating an own AnnotationView theGreatAnnotationView, but I want to keep the standard Annotation Pin on the map. In this code I use a custom annotation image view?.image = annotation.image but when is delete the line, there is no annotation on my map. Can you help me solving this problem?
func mapView(_ surroundingMapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
var annoView: MKAnnotationView?
if annotation.isKind(of: MKUserLocation.self) {
return nil
}
var view = surroundingMapView.dequeueReusableAnnotationView(withIdentifier: "imageAnnotation")
if view == nil {
view = theGreatAnnotationView(annotation: annotation, reuseIdentifier: "imageAnnotation")
reuseIdentifier: "imageAnnotation")
view!.canShowCallout = false
}
let annotation = annotation as! Artwork
view?.image = annotation.image
view?.annotation = annotation
return view
}
You should use MKPinAnnotationView instead of MKAnnotationView.
func mapView(_ surroundingMapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
var annoView: MKAnnotationView?
if annotation.isKind(of: MKUserLocation.self) {
return nil
}
if /* if annotation is image */ {
var view = surroundingMapView.dequeueReusableAnnotationView(withIdentifier: "imageAnnotation")
if view == nil {
view = theGreatAnnotationView(annotation: annotation, reuseIdentifier: "imageAnnotation")
view!.canShowCallout = false
}
let annotation = annotation as! Artwork
view?.image = annotation.image
view?.annotation = annotation
} else {
/* if annotation is pin */
var view = surroundingMapView.dequeueReusableAnnotationView(withIdentifier: "pinAnnotation")
if view == nil {
view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "pinAnnotation")
view!.canShowCallout = false
}
let annotation = annotation as! Artwork
view?.annotation = annotation
}
return view
}

Hide map pin annotation image

I am creating a map application which allows emojis to be attached to locations. Currently, the image is displayed above the stock apple map annotation.
I wish to hide the stock pin image while still displaying the selected emoji by the user. Is this possible?
I have this code so far to perform this:
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
//let identifier = "MyPin"
if annotation.isKindOfClass(MKUserLocation) {
return nil
}
let dictName = arrLocation[((annotation as? MyAnnotation)?.index)!]
let imgName = dictName.valueForKey("pin_img") as? String
var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(imgName!)
if annotationView == nil
{
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: imgName)
annotationView!.canShowCallout = false
let name = dictName.valueForKey("name") as! String
let annot = MyAnnotation(titleName:name)
annotationView?.annotation = annot
}
else
{
annotationView!.annotation = annotation
}
let detailButton: UIButton = UIButton(type: UIButtonType.Custom)
// size and placement of emoji on map
detailButton.frame = CGRectMake(-34,-25,85,85)
detailButton.tag = ((annotation as? MyAnnotation)?.index)!
detailButton.addTarget(self, action:"emojiTap:", forControlEvents: UIControlEvents.TouchUpInside)
detailButton.setBackgroundImage(UIImage(named:(dictName.valueForKey("pin_img") as? String)!), forState: UIControlState.Normal)
annotationView!.addSubview(detailButton)
return annotationView
}
Custom annotation view
Instead of using an MKPinAnnotationView, use its superclass MKAnnotationView.
Responding to input
To respond to the user tapping on an annotation implement the mapView:didSelectAnnotation: delegate method. This delegate method is called when the annotation is tapped.
Note that you do not need to use the button inside the annotation view. This means the functionality in emojiTap: must be implemented by the mapView:didSelectAnnotationMethod:.
Example
Combining these
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if annotation.isKindOfClass(MKUserLocation) {
return nil
}
let dictName = arrLocation[((annotation as? MyAnnotation)?.index)!]
let imgName = dictName.valueForKey("pin_img") as? String
var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(imgName!)
if annotationView == nil
{
annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: imgName)
let name = dictName.valueForKey("name") as! String
let annot = MyAnnotation(titleName:name)
annotationView?.annotation = annot
}
else
{
annotationView!.annotation = annotation
}
annotationView!.canShowCallout = false
return annotationView
}
func mapView(_ mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
guard let annotation = view.annotation as? MyAnnotation else {
return
}
print("tapped annotation: \(annotation.index)
// Implement the code from emojiTap: here.
}