从重用的自定义单元格中的按钮传递数据

时间:2016-09-03 11:56:15

标签: ios swift uitableview

我无法通过用户点击该自定义单元格中的按钮从自定义单元格传递数据。我有时会得到错误的单元格数据,因为单元格正在被重用。我想知道是否有完整的证明方式,无论当前在屏幕上哪个单元格,总是在每个单元格中获得正确的单元格数据。以下是我的代码。非常感谢任何帮助。

我的自定义单元格

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    
      }

    }
 }

4 个答案:

答案 0 :(得分:1)

我的自定义单元格:

protocol CustomCellDelegate {
  func segueWithCellData(cell:CustomTableViewCell)
}

class CustomTableViewCell : UITableViewCell {
  var delegate = CustomCellDelegate?

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

CustomCellDelegate方法:

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

因此,无需标记细胞。 由于您拥有所选单元格的indexPath,因此您可以从中获取数据,并通过sender方法的performSegueWithIdentifier参数传递此数据。

例如,

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)
}

并获取prepareForSegue内的数据,如下所示:

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    
      }
}

答案 1 :(得分:1)

我在几乎所有应用中使用的完整校对解决方案。在UIButton的类别类中创建NSIndexPath类型的自定义属性,并在cellForRowAtIndexPath函数中分配indexPath。现在,在按钮的回调中,通过数据源中的按钮indexPath.row找到索引处的对象。这永远不会失败。

答案 2 :(得分:0)

首先你必须在MyTableViewController中创建一个像这样的索引和标题字典:

<---Begin Code--->
echo "Which wire to cut? Red or Green? "
read die
if [[ die = "red" ]]; then
echo "You are saved!"
else echo "Dead,ciao in hell"
fi
<---End COde--->

在表视图中将单元格的标记设置为索引,并在MyTableViewController中将标题附加到titleDict:

var titleDict = [Int: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

    let index = indexPath.row
    cell.tag = index
    titleDict[index] = title
    cell.delegate = self        

    return cell
}

使用delegate方法中的给定索引从titleDict访问标题,并在MyTableViewController中设置为title变量:

protocol CustomCellDelegate {
  func segueWithCellData(index:Int)
}

class CustomTableViewCell : UITableViewCell {
  var delegate = CustomCellDelegate?

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

答案 3 :(得分:0)

简单解决方案:从数组(String)填充tableView并更新tableView。如果要更改tableView中的某些数据,则需要更新数组并刷新tableView。

我在我的应用程序中使用此解决方案,效果很好。