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

问题描述

我所拥有的: 我有一个CollectionViewCell作为.xib + .swift文件。 每个单元都从数据库获取数据。 在每个单元格中,我都有一个喜欢的按钮。

我想要什么: 当我按下某个单元格的“赞”按钮时,我希望能够读取此数据,以便可以对其进行更改并将新数据写入数据库中。所以我想更改某个单元格的数据集的like属性并将其保存在数据库

我尝试了什么: 我具有该单元格的indexPath,但是如何读取该单元格的数据?

    @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的数据。

如果您查看my answer on this thread,我将显示UITableView的扩展名,该扩展名使您可以确定哪个IndexPath包含一个按钮。几乎完全相同的方法适用于集合视图。这个想法很简单:

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

  • 询问拥有的表/集合视图以将这些坐标转换为 索引路径

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

唯一的区别是,对于集合视图,用来确定按钮映射到哪个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)
  ...
}

通常,单元永远不要在乎它的indexPath是什么,也不应该调用超级视图