Search code examples
iosswiftpushviewcontroller

Modifing one variable from another view controller swift


I am developing an app in Swift that, in gist, tells people the price of Bitcoin in various currencies. To select the currency, the user chooses from a list in a view controller with a UITableView. This is currencyViewController, and it is presented from my main screen, viewController.

What I want to happen is that, when the user dismisses currencyViewController, it passes a string to a UIButton in the main viewController.

Here's the prepareForSegue function that should pass the data:

 override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if (segue.identifier == "presentCurrency") {

        currencySelector.setTitle("\currencySelected", forState: UIControlState.Normal)

    }
}

CurrencySelector is a UIButton in the main viewController, and currencySelected is a variable in the second view controller, currencyViewController.

It gives the error "Invalid Escape Sequence In Literal"

So, I've narrowed it down to one of two issues:

  1. The variables from viewController can't be "seen" from currencyViewController. If so, how can I modify the text of CurrencySelector from CurrencyViewController?

  2. For some reason, when the user exits the pushed CurrencyViewControler, prepareForSegue isn't called.

What is going on here? Thanks, and apologies - I am but a swift newbie.


Solution

  • 2 - "prepareForSegue" is called when you push a new view controller via the segue, but not when you dismiss it. No segue is called upon dismissal.

    1 - A good way to do this would be the delegate pattern.

    So the main view controller would be the delegate for the currencyViewController, and would receive a message when that controller is dismissed.

    In the start of the currencyViewController file you prepare the delegate:

    protocol CurrencyViewControllerDelegate {
      func currencyViewControllerDidSelect(value: String)
    }
    

    and you add a variable to the currencyViewController:

    var delegate : CurrencyViewControllerDelegate?
    

    Now, the mainViewController has to conform to that protocol and answer to that function:

    class MainViewController : UIViewController, CurrencyViewControllerDelegate {
      //...  
    
      func currencyViewControllerDidSelect(value: String)  {
        //do your stuff here
      }
    }
    

    And everything is prepared. Last steps, in prepareForSegue (MainViewController), you will set the delegate of the currencyViewController:

    var currencyVC = segue.destinationViewController as CurrencyViewController
    currencyVC.delegate = self;
    

    And when the user selects the value in currencyViewController, just call that function in the delegate:

    self.delegate?.currencyViewControllerDidSelect("stuff")
    

    A bit complex maybe, but it's a very useful pattern :) here is a nice tutorial with more info if you want it:

    http://www.raywenderlich.com/75289/swift-tutorial-part-3-tuples-protocols-delegates-table-views