juelizabeth
juelizabeth

Reputation: 505

Send information to another View controller

I am having trouble getting the Indexpath of table view cell and sending it to a next page.

var bookName: String?

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

    print(posts[indexPath.row])
    let post = self.posts[indexPath.row] as! [String: AnyObject]
    self.bookName = post["title"] as? String
}

override public func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    guard segue.identifier == "sendMessageToUser", let chatVc = segue.destination as? SendMessageViewController else {
        return
    }
    chatVc.bookName = self.bookName
}

So I am trying to capture the title of whatever cell I clicked and send it to SendMessageViewController. The issue is that it captures some titles accurately and sometimes it does not capture the titles accurately, and I am not sure why.

Upvotes: 1

Views: 114

Answers (2)

Fangming
Fangming

Reputation: 25261

cellForRowAt method serves to create view, in this case a table view cell, and then provide that to table view to display. When table view loads data, you will see, say 10 cells. So this function is called 10 times to prepare the 10 cells. So in the last time, the index row will be 9 and your bookName property will be the 10th of your post array.

Now say you scroll down a bit and then scroll all the way up, the last cell getting prepared is the first cell. So now your bookName will be the first of your post array. That's why you are getting incorrect book name.

To fix your problem, you need to get the specific book name only after user clicked on a cell. So remove the code that assign values to bookName in your cellForRow method, and then add another delegate function like this

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let post = self.posts[indexPath.row] as! [String: AnyObject]
     self.bookName = post["title"] as? String
}

Upvotes: 1

Duncan C
Duncan C

Reputation: 131418

You need to implement the table view delegate method tableView(_:didSelectRowAt:). In that method, save the selected indexPath to an instance variable and invoke your segue.

Then in prepareForSegue, use the saved indexPath to index into your data model and fetch the data for the selected cell. (The title string, in your case.) Don't fetch the data from the cell's views. Views are not for storing data.

Upvotes: 2

Related Questions