Segue not getting selected row number

2020-06-04 02:24发布

I am passing data from a table view controller to a detail view. I tried using indexPath.row directly in my prepareForSegue method, however it displays an error of

use of unresolved identifier 'indexPath'

So, after searching the web, I set up the variable indexOfSelectedPerson which is assigned the value of indexPath.row. The problem when I run the app in the simulator is that prepareForSegue is getting the initial value of indexOfSelectedPerson (0), then getting the value of the selected row only after I click it. So, when I hit the back button in the Simulator and select a different row, the detail view shows the info of the row I selected the previous time.

import UIKit

class MasterTableViewController: UITableViewController {

    var people = []
    var indexOfSelectedPerson = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        people = ["Bob", "Doug", "Jill"]
    }

    override func numberOfSectionsInTableView(tableView: UITableView?) -> Int {
       return 1
    }

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

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

        let cell = tableView!.dequeueReusableCellWithIdentifier("personCell", forIndexPath: indexPath) as UITableViewCell

        cell.text = "\(people[indexPath.row])"

        return cell
    }

    override func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!)
    {
        indexOfSelectedPerson = indexPath.row
    }


    override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {

        if let mySegue = segue.identifier {

            if mySegue == "personDetails" {

                let detailsVC: DetailTableViewController = segue.destinationViewController as DetailTableViewController

                detailsVC.selectedPersonName = "\(people[indexOfSelectedPerson])"
            }
        }
    }
}

So, selecting Doug when the app first starts in the simulator displays the details for Bob because indexPathOfSelectedPerson is 0. Hitting the back button and then selecting Jill displays the details for Doug because indexPathOfSelectedPerson became 1 when I clicked on Doug the previous time. I'm guessing the problem stems from the order in which the methods are called.

3条回答
Bombasti
2楼-- · 2020-06-04 02:57

Swift 3 update:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let selectedIndex = tableView.indexPath(for: sender as! UITableViewCell)!
    // Do your actual preparing here...
}
查看更多
Explosion°爆炸
3楼-- · 2020-06-04 03:09
//In didSelectRowAtIndexPath, you use this code:

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

        self.performSegueWithIdentifier("yourSegueName", sender: nil)

    }

//And prepareForSegue to get IndexPath and send your value

override func prepareForSegue(segue: UIStoryboardSegue,
        sender: AnyObject!){

            let indexPath : NSIndexPath = self.yourTableView.indexPathForSelectedRow()!
            //make sure that the segue is going to secondViewController
            let detailsVC = segue.destinationViewController as DetailTableViewController
            detailsVC.selectedPersonName = "\(people[indexPath.row])"

    }
查看更多
何必那么认真
4楼-- · 2020-06-04 03:14

The best way to do this kind of thing is not to use the delegate.

Updated Swift 4+

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let selectedIndex = tableView.indexPath(for: sender as! UITableViewCell)
    // Do your stuff with selectedIndex.row as the index
}

Original Answer

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
    let selectedIndex = self.tableView.indexPathForCell(sender as UITableViewCell)
    // Do your stuff with selectedIndex.row as the index
}
查看更多
登录 后发表回答