Search code examples
iphoneswiftswift3mkmapviewios10

MKMapViewDelegate + JSON ALAMOFIRE


app download latitude and longitude from server on the 'moreViewController' I have label and when I tap pin how can I transform correct latitude or longitude (and image to another view) to this label?

{
  "latitude": 40.9233,
  "longitude": 20.000,
  "image" : "xxxx.xxx/xxx.jpg"
}
{
  "latitude": 50.9233,
  "longitude": 19.320,
  "image" : "xxxx.xxx/yyy.jgp"
}

So I download it and save to global var test = [String:AnyObject]()

Alamofire.request("website").responseJSON { response in

     print(response.result)   // result of response serialization
     let json = response.result.val
     print("JSON: \(json)" 
     let jsonTab = json as? Array<Any>
         for item in jsonTab as! [AnyObject] {
          self.test["lat"] = item["lat"] as? Double! as AnyObject?
          self.test["lng"] = item["lng"] as? Double! as AnyObject?
          self.addPin(lat: self.test["lat"] as! Double, lng: self.test["lng"] as! Double)

and add pin

func addPin(lat:Double, lng:Double) {
        let testPin = CLLocationCoordinate2D(latitude: lat, longitude: lng)
        let dropPin = MKPointAnnotation()
        dropPin.coordinate = testPin
        dropPin.title = "test"
        mapView.addAnnotation(dropPin)
    }

now add right button and segue to next view

func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
        self.performSegue(withIdentifier: "more", sender: self)
    }

    var annotationIdentifier = ""
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        var view = mapView.dequeueReusableAnnotationView(withIdentifier: annotationIdentifier)
        if view == nil {
            view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier)
            view?.canShowCallout = true
            view?.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
        } else {
            view?.annotation = annotation
        }
        return view
    }

    var selectedAnnotation: MKPointAnnotation!
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        if segue.destination is moreViewController {
            print("123")
            let destViewController:moreViewController = segue.destination as! moreViewController
            destViewController.lat = "\(latTest)"

        }
    }

Solution

  • With performSegue with sender instead of passing current controller reference pass the selected view's annotation.

    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
        self.performSegue(withIdentifier: "more", sender: view.annotation)
    }
    

    Now in prepareForSegue method access this sender property and get the annotation from it.

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    
        if segue.destination is moreViewController {
    
            let destViewController:moreViewController = segue.destination as! moreViewController
            if let annotation = sender as? MKAnnotation {
                destViewController.lat = "\(annotation.coordinate.latitude)"
                destViewController.long = "\(annotation.coordinate.longitude)"
            }
    
        }
    }
    

    Note: You have set lat and long value in test dictionary, so it will over write the value and it will contains only last array object's lat and long value.