maps navigation change annotation title & coordinates

i have a lot of annotations on a map and a link inside each annotationcallout, which forwards the user to the native mapsapp for a navigation process.


i created my link in here:

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        guard let annot = annotation as? customAnnotation else { return nil }

        if annotation is MKUserLocation {
            return nil
        }
        
        let annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "customAnnotation")
        annotationView.image = UIImage(named: annot.icon)
        annotationView.canShowCallout = true
        
        let rightButton = UIButton(type: .detailDisclosure)
        rightButton.setImage(UIImage(named: annot.isCollapsed ? "ic_showmore" : "ic_showless"), for: .normal)
        annotationView.rightCalloutAccessoryView = rightButton
        
        if (annot.isCollapsed) {
            annotationView.detailCalloutAccessoryView = nil
        }
        else {
            //create NavigationButton
            let naviButton = UIButton(type: UIButtonType.custom) as UIButton
            naviButton.setTitle(annot.address, for: .normal)
            naviButton.setTitleColor(.black, for: .normal)
            naviButton.titleLabel?.numberOfLines = 0
            naviButton.titleLabel?.font = UIFont.italicSystemFont(ofSize: 14.0)
            naviButton.frame = CGRect(x: 0, y: 0, width: 200, height: 21)
            naviButton.backgroundColor = .white
            naviButton.addTarget(self, action: #selector(naviButtonAction), for: .touchUpInside)
            annotationView.detailCalloutAccessoryView = naviButton
            
            naviButton.widthAnchor.constraint(lessThanOrEqualToConstant: naviButton.frame.width).isActive = true
            naviButton.heightAnchor.constraint(lessThanOrEqualToConstant: 90.0).isActive = true
        }
        return annotationView
}


and my "naviButtonAction" here:

@objc func naviButtonAction(sender: UIButton) {
        
        let latitude: CLLocationDegrees = 48.147989
        let longitude: CLLocationDegrees = 11.617287
        
        let regionDistance: CLLocationDistance = 1000;
        let coordinates = CLLocationCoordinate2DMake(latitude, longitude)
        let regionSpan = MKCoordinateRegionMakeWithDistance(coordinates, regionDistance, regionDistance)
        
        let options = [MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: regionSpan.center), MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan: regionSpan.span)]
        
        let placemark = MKPlacemark(coordinate: coordinates)
        let mapItem = MKMapItem(placemark: placemark)
        mapItem.name = "B"
        mapItem.openInMaps(launchOptions: options)
        
    }

now i want the coordinates and the title to change depending on the annotation the user has clicked. The question is just how?

i tried a little bit and never got a useful result, so i looked if my @objc func naviButtonAction can actually view the coordinates and title and tried printing them, but all it returned was "nil".


The title, coordinates, etc. where created for each annotation inside this for-loop in my override func viewDidLoad:

        for location in locations {
            let annotation = customAnnotation()
            annotation.title = location.title
            annotation.address = location.address
            annotation.oHour = location.oHour
            annotation.oMin = location.oMin
            annotation.cHour = location.cHour
            annotation.cMin = location.cMin
            annotation.coordinate = CLLocationCoordinate2D (latitude: location.latitude, longitude: location.longitude)

Any ideas why i cant call the title and how i can solve this?


Thanks a lot,

Gus

Replies

>tried printing them, but all it returned was "nil".


Might just be a problem with that statement...can you show it and where it is located, thanks.

Seems like the issue is how to get a reference to the *currently selected* annotation instance while in your button action method.


I can think of two approaches. You could keep track of which annotation has been selected yourself, by adding a property in your view controller. You would set this property when an annotation was selected, and clear it when deselected. This will work if there’s only one at a time with the callout showing.


Alternatively you could use the parameter passed to the action method - the sender - as a way to look up which annotation it came from. You would have to maintain a dictionary of buttons to annotations. You might be able to use the UIButton instance itself as a key, but myself I’d probably use an integer and store that integer in the button’s tag property. Then in your action method you’d get the tag from the button and look up in the dictionary which annotation it was associated with.


The first way would be easier I think, assuming only one at a time is not collapsed.

ok i sounds good

i just hope its not to much information for it to handle


atm moment i have roughly 200+ annotations and the app seems to have problems already: it just randomly moves around the map and selects random annotations the moment i touch the screen (doesnt happen with 5-10 annots stored)