CollectionViewCell:通过indexPath访问单元格的数据?

CollectionViewCell: Access to data of a cell through indexPath?

我有: 我有一个 CollectionViewCell 作为 .xib + .swift 文件。 每个单元格都从数据库中获取数据。 在每个单元格中,我都有一个“赞”按钮。

我想要的: 当我按下某个单元格的点赞按钮时,我希望能够读取此数据,以便更改它并将新数据写入数据库。所以想把某个cell的dataset的like属性改一下存到DB

我尝试了什么: 我有单元格的索引路径,但我如何读取单元格的数据?

    @IBAction func likeButton(_ sender: UIButton) {

        var superview = self.superview as! UICollectionView

        let buttonPosition:CGPoint = sender.convert(CGPoint.zero, to:superview)
        let indexPath = superview.indexPathForItem(at: buttonPosition)

        print(superview.cellForItem(at: indexPath!))
        
        // Change picture
        if sender.currentImage == UIImage(systemName: "heart.fill") {
            sender.setImage(UIImage(systemName: "heart"), for: .normal)
        } else {
            sender.setImage(UIImage(systemName: "heart.fill"), for: .normal)
        }
        
    }

UICollectionViewDataSource


    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MyCollectionViewCell.identifier,
                                                      for: indexPath) as! MyCollectionViewCell
        
        cell.backgroundColor = .white
        
        let newShoeCell = shoesArray?.randomElement()

        // Fill cells with data
        cell.imageView.image = UIImage(named: newShoeCell!.imgName)
        cell.shoeTitle.text = newShoeCell!.title
        cell.price.text = String(newShoeCell!.price)
        cell.ratingNumberLabel.text = String(newShoeCell!.meanRating)
        cell.floatRatingView.rating = newShoeCell!.meanRating
        
        if newShoeCell!.liked {
            cell.likeButtonOutlet.setImage(UIImage(systemName: "heart.fill"), for: .normal)
        } else {
            cell.likeButtonOutlet.setImage(UIImage(systemName: "heart"), for: .normal)
        }
        
        return cell
    }

你需要改变你的想法。它不是“单元格”的数据 单元格是视图对象。它向用户显示数据模型中的信息,并收集用户的输入。

您问“...我怎样才能读取单元格的数据?”简短的回答:不要。您应该随时将更改保存到您的数据模型中,因此一旦您有了索引路径,您应该使用它来索引到您的数据模型并从那里获取数据。

您需要找出点击的按钮属于哪个 IndexPath,并从您的数据模型中获取该 IndexPath 的数据。

如果您查看 ,我会展示 UITableView 的扩展,它可以让您找出哪个 IndexPath 包含一个按钮。几乎完全相同的方法应该适用于集合视图。思路很简单:

  • 在按钮操作中,获取按钮框架的坐标。

  • 要求拥有 table/collection 视图将这些坐标转换为 索引路径

  • 使用该索引路径获取数据。

唯一的区别是,对于集合视图,用于确定按钮映射到哪个 IndexPath 的方法是 indexPathForItem(at:) 而不是 indexPathForRow(at:)

我建议您在单元格中添加一个 属性

class MyCell: UITableViewCell {
var tapAction: (() -> Void)?
...
@IBAction func likeButton(_ sender: UIButton) {
  tapAction?()
  ...
}

}

并在视图控制器中设置它

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  ...
  cell.tapAction = { [weak self] in
  // call to database or whatever here and then reload cell
  tableView.reloadRows(at: [indexPath], with: .automatic)
  ...
}

一般来说,cell 不应该关心它的 indexPath 是什么,也不应该调用 superview