问题描述
我所拥有的: 我有一个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是什么,也不应该调用超级视图