user7748962
user7748962

Reputation:

Swift didSelectRowAt passing array values to second view

I am looking for ideas how to fix a problem I'm having with transposing data from my first view controller to the second view controller. The second view controller is being called when the user selects a table cell.

Code that populates the first tableview

public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = mtgRates.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ViewControllerTableViewCell

    cell.fiName.text = fetchedFiName[indexPath.row].fiName
    cell.oneYear.text = fetchedFiName[indexPath.row].oneYear
    cell.twoYear.text = fetchedFiName[indexPath.row].twoYear
    cell.threeYear.text = fetchedFiName[indexPath.row].threeYear
    cell.fourYear.text = fetchedFiName[indexPath.row].fourYear
    cell.fiveYear.text = fetchedFiName[indexPath.row].fiveYear


            return (cell)

}

I've watched many youtube videos but they all take a simple approach when setting up the data using an array set globally.

Code that I have been working but does nothing at this point.

 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {


        oneYearFound = self.fetchedFiName[indexPath.row].oneYear
        twoYearFound = self.fetchedFiName[indexPath.row].twoYear
        threeYearFound = self.fetchedFiName[indexPath.row].threeYear
        fourYearFound = self.fetchedFiName[indexPath.row].fourYear
        fiveYearFound = self.fetchedFiName[indexPath.row].fiveYear

    performSegue(withIdentifier: "segue", sender: self)



}

I am thinking my issues is sending the fetched results to the second view controller

Thank you for any help!


More info based on the reply. You are correct I do have two view controllers on the storyboard. The code I have this far my UIViewController is

class SegueViewController: UIViewController {

@IBOutlet weak var V2TwoYear: UILabel!
@IBOutlet weak var V2FiveYear: UILabel!
@IBOutlet weak var V2FourYear: UILabel!
@IBOutlet weak var V2ThreeYear: UILabel!
@IBOutlet weak var V2OneYear: UILabel!
@IBOutlet weak var V2FiName: UILabel!

override func viewDidLoad() {

    super.viewDidLoad()

    V2FiName.text = foundFi[myIndex].fiName
    V2TwoYear.text = foundFi[myIndex].twoYear
    V2OneYear.text = foundFi[myIndex].oneYear
    V2ThreeYear.text = foundFi[myIndex].threeYear
    V2FourYear.text = foundFi[myIndex].fourYear
    V2FiName.text = foundFi[myIndex].fiveYear

}

Upvotes: 1

Views: 984

Answers (2)

pesch
pesch

Reputation: 1996

Why don't you pass an instance of your fetchedFiName?

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let selectedFiName = self.fetchedFiName[indexPath.row]
        performSegue(withIdentifier: "segue", sender: selectedFiName)
}

Then, cast your sender as YOUR_FETCHED_FI_NAME_CLASS and pass it to your destination view controller in prepareForSegue:

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

    if let selectedFiName = sender as? YOUR_FETCHED_FI_NAME_CLASS,
        destVC = segue.destination as? SegueViewController {
        destVC.passedFiName = selectedFiName
    }
  }

Then, in your destination viewController and after ViewDidLoad (since your labels will not be loaded before that) you may use your passedFiName to populate your labels.

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

func updateLabels() {
    V2FiName.text = passedFiName.fiName
    V2TwoYear.text = passedFiName.twoYear
    V2OneYear.text = passedFiName.oneYear
    V2ThreeYear.text = passedFiName.threeYear
    V2FourYear.text = passedFiName.fourYear
    V2FiName.text = passedFiName.fiveYear
}

Update:

I continue to have problems with this. I think I am getting closer

Controller one code

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {


    let selectedFiName = self.fetchedFiName[indexPath.row].fiName
    let selectedOneYear = self.fetchedFiName[indexPath.row].oneYear
    let selectedTwoYear = self.fetchedFiName[indexPath.row].twoYear
    let selectedThreeYear = self.fetchedFiName[indexPath.row].threeYear
    let selectedFourYear = self.fetchedFiName[indexPath.row].fourYear
    let selectedFiveYear = self.fetchedFiName[indexPath.row].fiveYear

    passData = [SecondTable(passedFIName: selectedFiName, passedOneYear: selectedOneYear, passedTwoYear: selectedTwoYear, passedThreeYear: selectedThreeYear, passedFourYear: selectedFourYear, passedFiveYear: selectedFiveYear)]


   performSegue(withIdentifier: "SecondViewController", sender: self)


}

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

    if let selectedFiName = sender as!  ,
        let destVC = segue.destination as? SecondViewController {
        destVC.fiName = selectedFiName
    }
}

Second View Controller Code`

struct SecondTable {

var passedFIName: String = ""
var passedOneYear: String = ""
var passedTwoYear: String = ""
var passedThreeYear: String = ""
var passedFourYear: String = ""
var passedFiveYear: String = ""

}

class SecondViewController: UIViewController {

@IBOutlet weak var fiName: UILabel!
@IBOutlet weak var sometext: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

    let fiDetails = SecondTable()

    fiName.text = .passedFIName
    sometext.text = "Some Text"


}

}

I am getting error messages at` override func prepare(for segue: UIStoryboardSegue, sender: Any?) { I am nit sure what to put after "Sender as "Missing value"

I have been searching for hours. One I solve this problem. my project will start to move along. Thank you for all the great help!`

Upvotes: 1

Ganksy
Ganksy

Reputation: 48

I need to make a few assumptions:

  1. You have a storyboard with a seque with the identifier "seque"
  2. You have a view controller at the end of that seque.
  3. You need to send oneYearFound.... all 5 of those values to the SecondViewController. Lets just say that view controller has 5 UILabels that display the five values you want to send.

Sounds like SecondViewController needs some sort of object to hold those values. Define one on that view controller, and then create a prepareForSeque method on your FirstViewController. Source

In prepareForSeque, get the destination view controller off the seque and then pass it the object.

Then use the object to populate the values for the labels in ViewDidAppear or ViewDidLoad.

Edit:

It looks like you're really close. Make sure you dont forget to include the PrepareForSeque method in the first view controller. Inside that method override you can access the second view controllers instance and set those array values.

Here is some code that should help get you thinking.

class LabelsClass {
  var str1:String;
  var str2:String;

  init(firstName:String, secondName:String) {
    str1 = firstName;
    str2 = secondName;
  }
}

class SegueViewController: UIViewController {
  var firstLabelString:String = ""
  var secondLabelString:String = ""


  func setValues(labels:LabelsClass) {
    self.firstLabelString = labels.str1;
    self.secondLabelString = labels.str2;
  }
}


class MessageListViewController: UIViewController {


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

    var first = "Game"
    var second = "maniac"

    var localLabelsVar = LabelsClass.init(firstName: first,secondName: second);

    var destVC = segue.destination as? SegueViewController
    destVC?.setValues(labels: localLobalsVar)
  }

}

Sources: How do I use prepareForSegue in swift?

How to pass prepareForSegue: an object

Upvotes: 0

Related Questions