Passing data back from view controllers Xcode
Asked Answered
H

3

15

A couple of weeks ago I asked this question and got a very detailed explanation. Now I would like to pass data back to the first ViewController but I keep getting stuck using the same method. I have a modal of the first VC to the second, where I would like to edit an array of strings, which will be showed on the first view again. So on my first view I have an array of data, which should be passed to the second so edit fields show the current information after which the user has to be able to edit the contents of the array and pass that data back to the first where it is shown on labels. I'm using Swift.

My code:

(in ViewController.swift:)

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
        let secondVC = segue.destinationViewController as SecondViewController
        secondVC.namesPlayers = self.namesPlayers
    }

(in SecondViewController.swift:)

override func viewDidLoad() {
    super.viewDidLoad()
    labelFirstPlayer.text = namenSpelers[0]
}

Thank you

Hop answered 27/8, 2014 at 8:57 Comment(2)
Where is your code ?Ethbin
Sorry, I updated my OPHop
B
37

You need to use a delegate. Here is an example how do use a delegate in Swift.

On your first ViewController, set your delegate when you load the second VC:

For example, if you are using the Storyboard Editor:

var secondViewController = (segue.destinationViewController.visibleViewController as  MySecondViewControllerClass)
secondViewController.delegate = self

Write a Protocol and define a func to write you values back

For example, create a file called "Protocol.swift" and write something like that:

protocol writeValueBackDelegate {
    func writeValueBack(value: String)
}

Add the function to your FirstViewController

func writeValueBack(value: String) {
   // Or any other function you need to transport data
}

And to your ViewControllerClass

class ViewController: UIViewController, writeValueBackDelegate

The above line will not work if you have not implemented all of the methods in ViewController that you defined in your protocol file.

Go to the Second View Controller, and add the delegate here:

class SecondViewController: ViewController {

    // Delegate for FirstViewController
    // Declare as weak to avoid memory cycles
    weak var delegate: writeValueBackDelegate?
}

On your Second View Controller, you can now use this to call the func in the first View Controller an pass data.

delegate?.writeValueBack("That is a value")
Barely answered 27/8, 2014 at 9:5 Comment(5)
You also need to indicate that your first view controller implements the protocol: class ViewController: UIViewController, writeValueBackDelegate {Brennen
Can't we use closures here to achieve the same?Bolger
@Barely Can I to make a reverse way that I manage data from FirstViewController into SecondViewController? ThanksTint
For sure: Check out my answer here: #26089652Barely
Should var secondViewController = (segue.destinationViewController.visibleViewController as MySecondViewControllerClass) secondViewController.delegate = self be put in the prepare for segue method?Fixate
F
0

I'm confused by the answer using delegates, because it seems to me needlessly complicated. Here's what I did to pop-up an Add Player dialog in my card game, and pass the results back to the calling view controller.

Add delegate protocol (in my case in my Extensions/Protocols file)

protocol ReturnPlayerInfoDelegate {
   func returnPlayerInfo(playerName : String, playerType : Player.Type)
}

Then I added my reference (as a class var) to the delegate in the CALLED View Controller. Note this didn't require my subclassing my caller, or adding the protocol to my called View Controller:

class AddPlayerViewController : UIViewController {
     static var delegate : ReturnPlayerInfoDelegate!

and called the delegate in my Ok button handler:

    @IBAction func onOK(sender: UIButton) {
      AddPlayerViewController.delegate.returnPlayerInfo(mPlayerName.text!, playerType: mPlayerTypeActual)
    dismissViewControllerAnimated(true, completion: nil)
}

Now I implemented the delegate in the CALLING ViewController:

class FiveKings : UIViewController, UIGestureRecognizerDelegate, UIPopoverPresentationControllerDelegate ,UITextViewDelegate , ReturnPlayerInfoDelegate {
...
    override func viewDidLoad() {
         super.viewDidLoad()

         AddPlayerViewController.delegate = self
...
    func returnPlayerInfo(playerName : String, playerType : Player.Type) {
        mGame.addPlayer(playerName, newPlayerClass: playerType, fKActivity: self)
}

This works very nicely. Do you see any problems with my implementation?

Folse answered 19/1, 2016 at 18:11 Comment(2)
You said you were confused by the answer using delegates. And you also use delegate in your answer. What did you mean you were confused?Andres
You also need to make sure that your delegate variable is weak to prevent a memory cycle static weak var delegate : ReturnPlayerInfoDelegate?Skilled
V
0

Hope this will help you

This the second controller from where you want to return data to pushed. SecondView.swift

@objc protocol returnDataProtocol {
    func returnStringData(myData: String)
 }




 class SecondView: UIViewController {


        weak var delegate: returnStringData?


        @IBAction func readyButtonPressed(sender: AnyObject) {

        // Do what you want here 

        delegate?.returnStringData("Euro/Dollar etc....")
         // this function is exist in first view controller 

        }
    }

First view ViewController firstView.swift

class firstView: UIViewController, returnDataProtocol {
    // this function will call to second view. You can use here push method, if you are using navigation controller. 
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "mySegue" { // your identifier here
            let controller = segue.destinationViewController as! MyPopOverController
            controller.delegate = self
        }
    }

   // here you will get return value from second view controller class

    func returnStringData(myData: String){
          print(myData)
       }

}
Vacation answered 21/6, 2017 at 11:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.