kampbell411 kampbell411 - 3 months ago 17
iOS Question

Pass data from a button in reused custom cell

I'm having trouble passing data from a custom cell by a user tapping a button in that custom cell. I sometimes get the wrong cells data since the cell is being reused. I was wondering if there was a full proof way to always get the right cell data to its button in each cell no matter which cell is currently on the screen. Below is my code. Any help is greatly appreciated.

My Custom Cell:

protocol CustomCellDelegate {
func segueWithCellData()
}

class CustomTableViewCell : UITableViewCell {
var delegate = CustomCellDelegate?

@IBAction func buttonTapped() {
if let delegate = self.delegate {
delegate.segueWithCellData()
}
}
}


MyTableViewController:

class MyTableViewController : UITableViewController, CustomCellDelegate {
var posts = [Post]()
var title: String!

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let post = posts[indexPath.row]
let cell = tableView.dequeueReusableCellWithIdentifier("CustomCellReuseIdentifier", forIndexPath: indexPath)
title = post.title

cell.delegate = self

return cell
}

func segueWithCellData() {
self.performSegueWithIdentifier("passMyData", sender: self)
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == “passMyData” {
let destination = segue.destinationViewController as! UINavigationController
let targetVC = destination.topViewController as! nextVC
targetVC.title = title
}

}
}

Answer

My Custom Cell:

protocol CustomCellDelegate {
  func segueWithCellData(cell:CustomTableViewCell)
}

class CustomTableViewCell : UITableViewCell {
  var delegate = CustomCellDelegate?

  @IBAction func buttonTapped() {
    if let delegate = self.delegate {
        delegate.segueWithCellData(self)
     }
   }
}

CustomCellDelegate Method:

func segueWithCellData(cell:CustomTableViewCell) {
    //Get indexpath of selected cell here
    let indexPath = self.tableView.indexPathForCell(cell)
    self.performSegueWithIdentifier("passMyData", sender: self)
}

Hence, no need of tagging cell. Since, you have indexPath of the selected cell, you can get data from this and pass this through sender parameter of performSegueWithIdentifier method.

For example,

func segueWithCellData(cell:CustomTableViewCell) {
    //Get index-path of selected cell here
    let selectedIndexPath = self.tableView.indexPathForCell(cell)
    let post = posts[selectedIndexPath.row]

    self.performSegueWithIdentifier("passMyData", sender: post)
}

and, get the data inside prepareForSegue as follows:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
     if segue.identifier == “passMyData” {
        let destination = segue.destinationViewController as! UINavigationController
        let targetVC = destination.topViewController as! nextVC

        //Get passed data here
        let passedPost = sender as! Post

        targetVC.title = title    
      }
}