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
Related
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
}
I managed to make my annotations with a personalized image by annotation and the title in the popup.
My question: Is it possible to also add the title below the annotation?
Thank you in advance for your feedback.
The view controller
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
let pageDecouverte = listeDesPoints[view.tag]
selectedLieuDecouverte = pageDecouverte
self.performSegue(withIdentifier: "showPageDecouverte", sender: nil)
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?
{
if !(annotation is MKPointAnnotation) {
return nil
}
let annotationIdentifier = "location"
var annotationView = carteRegion.dequeueReusableAnnotationView(withIdentifier: (annotationIdentifier))
if annotationView == nil {
annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier)
annotationView!.canShowCallout = true
}
else {
annotationView!.annotation = annotation
}
if annotation is MyAnnotation {
let imageName = (annotation as! MyAnnotation).imageName
annotationView?.tag = (annotation as! MyAnnotation).tag
if imageName != nil{
let interetImage = UIImage(named: imageName!)
annotationView!.image = interetImage
}
}
annotationView?.clusteringIdentifier = annotationIdentifier
annotationView?.canShowCallout = true
annotationView?.rightCalloutAccessoryView = UIButton(type:.detailDisclosure)
return annotationView
}
}
For my MyAnnotation
import UIKit
import MapKit
import Parse
class MyAnnotation: MKPointAnnotation {
var imageName: String?
var annotationTitle: String?
var tag : Int = 0
var pageDecouverte:PFPageDecouverte?
}
Instead of MKAnnotationView use the subclass MKMarkerAnnotationView to render the title below the marker.
Also in MyAnnotation rename annotationTitle to title, then MKMarkerAnnotationView automatically knows what to render.
See the definition of protocol MKAnnotation to see why.
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
}
}
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
}
I want to create a info window for a Google map marker to provide a button click event inside the info window in my iOS application. Is there any way to do this?
Hope this can help you
extension ViewController: MKMapViewDelegate {
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
}
let identifier = "MyCustomAnnotation"
var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier)
if annotationView == nil {
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView?.canShowCallout = true
} else {
annotationView!.annotation = annotation
}
let myButton = UIButton()
annotationView?.leftCalloutAccessoryView = myButton
return annotationView
}
}