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
我有: 我有一个 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 的数据。
如果您查看
在按钮操作中,获取按钮框架的坐标。
要求拥有 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