【问题标题】:CollectionViewCell: Access to data of a cell through indexPath?CollectionViewCell:通过indexPath访问单元格的数据?
【发布时间】:2020-09-17 15:31:09
【问题描述】:

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

我想要的: 当我按下某个单元格的like按钮时,我希望能够读取这些数据,以便我可以更改它并将新数据写入数据库。所以我想更改某个单元格的数据集的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
    }

【问题讨论】:

    标签: swift uicollectionviewcell collectionview


    【解决方案1】:

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

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

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

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

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

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

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

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

    【讨论】:

    • 您好,谢谢您的回答!但我认为你还没有阅读我的代码。我已经得到了 indexPath,问题是:当我有 indexPath 时如何获取我的数据。期待您的回答。
    • 两点: 1. 您的代码假定您的按钮位于 UICollectionView 的下一级。那是脆弱的。如果您决定添加堆栈视图、在其他视图中分组视图或更改单元格的结构,它将中断。看看我的扩展。它更可靠。
    • 第二:当用户与不同的字段交互时,您应该随时将用户所做的任何更改保存到您的模型对象中。例如,如果用户在文本字段中输入文本,然后将单元格滚动到屏幕外,如果您尚未将更改保存到模型,它们将会丢失。拥有 IndexPath 后,使用它来索引模型对象并获取该 IndexPath 的数据。
    • 我已经实现了你的扩展。它工作得很好,我像以前一样得到了 indexPath,但是以更好的方式,谢谢你。但是我现在如何获取数据?这是我的主要问题^^
    • 通常对于行列集合视图或分段表视图,您的模型对象可能是结构数组的数组,其中结构包含您在单元格中显示的所有字段。当用户进行更改时,您会更新 yoru 数组中该条目中的结构。要获取值,您将从模型数组数组中的适当数组索引中获取结构。
    【解决方案2】:

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

    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

    【讨论】:

    • 让你的按钮调用闭包是解决问题的好方法。几个 cmets:OP 询问的是集合视图,而不是表视图。此外,您不需要也不应该在集合视图/表格视图的 cellForRowAt/ItemForRowAt 方法中调用 reloadRows。这将导致一个无限循环,您提供一个单元格,然后告诉集合/表格视图重新加载它,因此它会再次要求您提供单元格,无限循环。
    • 我的错,但集合视图的解决方案看起来非常相似。此外,在这种特殊情况下,不会出现无限循环,因为重新加载单元格不会触发对闭包的调用。
    • 哦,我看错了你的代码。您对 reload 的调用在按钮关闭中。我的错。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-20
    • 2015-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多