After selecting a TableView Cell, pass the data back to the previous View Controller in Swift

2.9k views Asked by At

There seems to be a lot of tutorials online for this, but I cant find one that passes the value back from a TableView Controller to the first View Controller.

Here's my set up... The first ViewController has a textfield, when the user presses in it, it takes them to the second TableViewController, where they can select a country from the list. Once they have selected it, I want them to press the DONE button on the Navigation Bar, and then I want it to segue back to the first ViewController and show the Country they selected in the textfield (ready for them to press a button and the app continues etc...)

From what I can work out, I need to do this in the DidSelectRowAtIndexPath method...? But I also keep seeing talk on unwind segues? Sorry I am new to Swift and iOS code, so would appreciate a clear answer on what is the best and easiest way to do this. Please see my code below for each controller:

ViewController

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

@IBOutlet var textField: UITextField!

override func viewDidLoad() {
    super.viewDidLoad()

}

func textFieldShouldBeginEditing(textField: UITextField) -> Bool {

performSegueWithIdentifier("countryTableView", sender: self)

return false

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}

TableViewController

import UIKit

class TableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

@IBOutlet var tabeView: UITableView!

var countryPicker = ["Colombia", "England", "France", "Germany", "Brazil", "Austria", "Spain", "Australia", "USA", "Berlin", "Thailand", "Northern Ireland", "New Zealand", "Hawaii", "Switzerland", "Sweeden", "Finland", "Turkey", "Russia", "Netherlands", "Japan"]

override func viewDidLoad() {
    super.viewDidLoad()

}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return countryPicker.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("UITableViewCell") as! UITableViewCell

    cell.textLabel!.text = countryPicker[indexPath.row]

    cell.selectionStyle = UITableViewCellSelectionStyle.Blue

    return cell
}

}

Thanks in advance!

4

There are 4 answers

1
Carl Carlson On

In the original view controller add a IBAction that you want to handle the call back.

In IB Control Drag from the cell to the Exit icon at the top of the view. On release you will see a a pop up menu with the name of available IBAction methods. Choose your IBAction method.

I don't remember wether if you add a sender variable to the IBAction, you can retrieve info from it.

1
chrisamanse On

Add a weak var previousVC: UIViewController containing your previous view controller in your second view controller (your table view controller). Before going to your second view controller, add a prepareForSegue method in your first view controller, and access your second view controller using let destinationVC = segue.destinationViewController then destinationVC.previousVC = self. You now have access to your previous controller, where you can pass any data you want by adding a property to your first view controller.

Code:

class ViewController: UIViewController, UITextFieldDelegate {

@IBOutlet var textField: UITextField!

var myObject: Object? // Some object you will pass
override func viewDidLoad() {
    super.viewDidLoad()

}

func textFieldShouldBeginEditing(textField: UITextField) -> Bool {

performSegueWithIdentifier("countryTableView", sender: self)

return false

}
...

func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "countryTableView" {
        let tableVC = segue.destinationViewController as! TableViewController
        // Pass the object
        tableVC.passedObject = myObject
    }
}
}


class TableViewController.... {
var passedObject: Object // The object to be passed
...
}
0
Pradeep Kumar On

Second ViewController

import UIKit

class TableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

@IBOutlet var tableView: UITableView!

var countryPicker = ["Colombia", "England", "France", "Germany", "Brazil", "Austria", "Spain", "Australia", "USA", "Berlin", "Thailand", "Northern Ireland", "New Zealand", "Hawaii", "Switzerland", "Sweeden", "Finland", "Turkey", "Russia", "Netherlands", "Japan"]

var delegate: CountrySelectionDelegate?

override func viewDidLoad() {
    super.viewDidLoad()
    
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    
    return countryPicker.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    
    let cell = tableView.dequeueReusableCellWithIdentifier("UITableViewCell") as! UITableViewCell
    
    cell.textLabel!.text = countryPicker[indexPath.row]
    
    cell.selectionStyle = UITableViewCellSelectionStyle.Blue
    
    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let country = countryPicker[indexPath.row]
    self.delegate.countryDidSelect(country: country)
    self.navigationController?.popViewController(animated: true)
}

}

protocol CountrySelectionDelegate { func countryDidSelect(country: String) }

0
Pradeep Kumar On

First ViewController

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

@IBOutlet var textField: UITextField!
@IBOutlet var lblCountry: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()
    
}

func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
    
    performSegueWithIdentifier("countryTableView", sender: self)
    
    return false
    
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBAction func gotoSecondVC(_ sender: Any) {
    let secondVc = self.storyboard?.instantiateViewController(identifier: "TableViewController") as! TableViewController
    secondVc.delegate = self
    navigationController?.pushViewController(true, animated: true)
}

}

extension ViewController: CountrySelectionDelegate {

func countryDidSelect(country: String) {
    lblCountry.text = country
}

}