Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift: Data is not being stored in variable when passing through VC

Tags:

ios

swift

I'm trying to store the name of a map pin in a variable, then display it on a label on my second VC.

Currently, this is what I've got.

FirstVC.swift

//Perform segue when callout has been tapped
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {

     self.performSegue(withIdentifier: "showAnnotationInfo", sender:view)

        }


func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {

    print("Annotation selected")

    if let annotation = view.annotation as? POIAnnotations {
        print("Your annotation title is: \(annotation.title!)")

        // Instantiate ShopDetailViewController
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let destVC = storyboard.instantiateViewController(withIdentifier: "shopDetailVC") as! ShopDetailViewController

        destVC.shopNameData = annotation.title!
        print("Shop name data has the value: \(destVC.shopNameData)")

    }
}

ShopDetailViewController.swift

class ShopDetailViewController: UIViewController {

@IBOutlet weak var shopName: UILabel!

var shopNameData = "data"

override func viewDidLoad() {
    super.viewDidLoad()

    self.shopName.text = self.shopNameData
    print(shopNameData)

  }

}

What is happening is, when I attempt to store annotation.title in shopNameData, there is no problem.

However, when I click on the annotation, the data from annotation.title is no longer stored in shopNameData and simply displays the default data.

enter image description here

I'm not sure where I've gone wrong here.

EDIT

I've included where I present ShopDetailViewController.

like image 321
daanyyaal Avatar asked Oct 30 '22 15:10

daanyyaal


1 Answers

You are simply creating an instance of the ShopDetailViewController, setting the value and then doing nothing with it. The instance of ShopDetailViewController that you created goes out of scope and gets deallocated.

How are you presenting the ShopDetailViewController? Are you using a segue? If you are then you should override the prepareForSegue() method where you will get an instantiated version of the ShopDetailViewController which will be presented and not go out of scope and then simply set the shopNameData property in there.

EDIT:

Thanks for clarifying the way you are presenting the view controller. So to answer you comment:

You need to go to FirstVC and add something like the following code:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if let viewController = segue.destination as? ShopDetailViewController,
        let annotationView = sender as? MKAnnotationView,
        let annotation = annotationView.annotation as? POIAnnotations {

        viewController.shopNameData = annotation.title
    }
}

Then after that you can just remove the code in your func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) method and keep the code in your func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) method.

This way you are simply calling present and passing the MKAnnotationView through as the sender, then pulling out the relevant information when the segue is preparing to present your view controller. I hope that makes sense.

like image 127
dlbuckley Avatar answered Nov 15 '22 06:11

dlbuckley