1

first time asking after learning many useful things here!

I have a VC1 with a button and label. The button is coded to present VC2 programmatically (without segue in IB). VC2 has a tableview with the cells containing string values.

When I click on the cell in VC2, I am trying to get the string value of the selected cell and pass it back to the label.text in VC1.

First ViewController code:

class VC1: UIViewController {
    ... ...

    @IBOutlet weak var LabelText: UILabel!
    var passedString = "Example"

    override func viewWillAppear(animated: Bool) {
        LabelText.text = "\(passedString)"
    }

    @IBAction func chooseLabelTextBtnPressed(sender: AnyObject) {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let vc = storyboard.instantiateViewControllerWithIdentifier("VC2") as! VC2
        self.presentViewController(vc, animated: true, completion: nil)
}

SecondViewController code:

class VC2: UIViewController, UITableViewDelegate, UITableViewDataSource {    
    ... ...

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    // Get Cell Label
    let indexPath = tableView.indexPathForSelectedRow;
    let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as! VC2_tableViewCell!;
    let valueToPass = currentCell.IBOutletLbl.text
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let viewController = storyboard.instantiateViewControllerWithIdentifier("VC1") as! VC1
    viewController.passedString = valueToPass!

    //self.presentViewController(viewController, animated: true , completion: nil)

    self.dismissViewControllerAnimated(true, completion: nil)
}

I hoped func viewWillAppear() in VC1 would update the String value of the label when VC2 is dismissed, but it doesn't.

I cannot use presentViewController from VC2 to VC1, because it might open again the VC1 instead of going back, and then other variables in VC1 would be inaccessible.

Help me! Thanks!

Juno Ken
  • 43
  • 3
  • let viewController = storyboard.instantiateViewControllerWithIdentifier("VC1") as! VC1 => this viewController is not the VC1 you are referring to. This is a new object. You need to get the VC1 reference from the navigation controllers' viewControllers list or when VC1 presented VC2, pass itself as a reference to VC2. – Surely Mar 11 '16 at 18:41
  • You can use delegation. Take a look at this answer: http://stackoverflow.com/a/27457890/1630618 – vacawama Mar 11 '16 at 18:44
  • I am wondering why you are not using a segue from the Storyboard. You can create an unbound segue and use it programatically. – ryantxr Mar 11 '16 at 19:17

2 Answers2

1

You should pass a delegate from VC1 to VC2 and then just call a delegate method for the update.

Send a reference here to VC2.

@IBAction func chooseLabelTextBtnPressed(sender: AnyObject) {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let vc = storyboard.instantiateViewControllerWithIdentifier("VC2") as! VC2
        vc.delegate = self
        self.presentViewController(vc, animated: true, completion: nil)
}

And before calling self.dismissViewControllerAnimated(true, completion: nil) in VC2 just call delegate.someMethod(someValue)

Also make sure your delegate is a weak reference.

Stefan Salatic
  • 4,513
  • 3
  • 22
  • 30
  • I added a protocol with func updateLabel(labelString: String) in VC2. Created a delegate variable in VC2. And: @IBAction func saveBtnPressed(sender: AnyObject) {let indexPath = tableView.indexPathForSelectedRow let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as! VC2_Cell let stringToPass = currentCell.VC2CellLbl.text self.delegate?.updateLabel(stringToPass!) self.dismissViewControllerAnimated(true, completion: nil)}. After in VC1: func updateLabel(labelString: String) {self.passedString = "\(labelString)"}. What am I doing wrong? – Juno Ken Mar 11 '16 at 21:45
  • Ah!!! I gotcha! I omitted vc.delegate = self in the IBAction button in VC1 to get to the VC2. I did it and it works! Thanks a zillion! – Juno Ken Mar 11 '16 at 21:53
0

When you do this:

let viewController = storyboard.instantiateViewControllerWithIdentifier("VC1") as! VC1

It creates a new instance of VC1 and doesn't actually reference the VC1 that presented VC2.

Instead you should add delegation between VC1 & VC2 to pass data around.

Forrest
  • 620
  • 1
  • 6
  • 13