Runeaway3
Runeaway3

Reputation: 1449

Prepare for segue returning nil for indexPathForSelectedRow?

I want to pass information from an array from one viewController to another based on what row was selected in my tableView. To do this I have implemented the following functions:

func tableView(_ messagesListTableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        messagesListTableView.deselectRow(at: indexPath, animated: true)
        performSegue(withIdentifier: "individualMessageSegue", sender: self)
        print(indexPath)//returns [0,0]... meaning the first row
    }
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        guard segue.identifier == "individualMessageSegue" else{return}

        if let indexPath = self.messagesListTableView.indexPathForSelectedRow{
            let openedMessageConversation = fullOrderedMessageArray[(indexPath.row)] //cause app to crash because nil value
            let destViewController: IndividualMessageVC = segue.destination as! IndividualMessageVC
            destViewController.messageConvo = openedMessageConversation
        }else{
            print("it was nil")
        }

    }

I believe I have everything set up correctly, however despite the print statement from the didSelectRowAt always returning a value for the indexPath of [0,0] (in the table there is only one section and one row), the print statement in prepare always tells me that the indexPath is nil. If I remove the if let conditional, the app will crash because fullOrderedMessageArray[(indexPath.row)] contains the nil value. I have no idea why it keeps returning nil for one function while not for the other.

Upvotes: 0

Views: 567

Answers (2)

BangOperator
BangOperator

Reputation: 4447

The culprit here is

messagesListTableView.deselectRow(at: indexPath, animated: true)

By this line you have asked your tableview to deselect the selected row. After this statement there is no row selected hence, when you ask the table view to return the selected row it gives nil

self.messagesListTableView.indexPathForSelectedRow // will be nil

Though, Bapu has provided a solution to your problem, but this is the answer to your question, "Prepare for segue returning nil for indexPathForSelectedRow?"

Just comment out the messagesListTableView.deselectRow(at: indexPath, animated: true) and your old code will work as expected.

Upvotes: 1

Bapu
Bapu

Reputation: 94

Can you try this.

func tableView(_ messagesListTableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    messagesListTableView.deselectRow(at: indexPath, animated: true)
    performSegue(withIdentifier: "individualMessageSegue", sender: indexPath)
    print(indexPath)//returns [0,0]... meaning the first row
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    guard segue.identifier == "individualMessageSegue" else{return}

    if let indexPath = sender as? IndexPath {
        let openedMessageConversation = fullOrderedMessageArray[(indexPath.row)] 
        let destViewController: IndividualMessageVC = segue.destination as! IndividualMessageVC
        destViewController.messageConvo = openedMessageConversation
    }else{
        print("it was nil")
    }

}

Upvotes: 2

Related Questions