我有一个收集视图,其中每个单元格都具有与用户进行交互的能力。每个单元格都有一个like
按钮和一个number of likes
标签。当按下按钮时,按钮应变成青色,标签(包含点赞次数)应增加。此设置当前有效。但是,当我在集合视图中滚动并向后滚动时,该按钮将还原为其原始颜色(白色),并且标签递减至其原始值。我听说过一种叫做prepareForReuse()
的有用方法,但是也许我没有正确使用它。这是我的代码:
这里是包含所有单元格的数组
var objects = [LikableObject]()
这是这些对象的类定义
class LikableObject {
var numOfLikes: Int?
var isLikedByUser: Bool?
init(numOfLikes: Int, isLikedByUser: Bool) {
self.numOfLikes = numOfLikes
self.isLikedByUser = isLikedByUser
}
}
请记住,此对象中存在更多功能,但是对于此问题而言,它们无关紧要。需要注意的重要一件事是,使用API抓取每个单元格的数据。我正在使用Alamofire向API发出请求,该API将为每个单元格返回numOfLikes
和isLikedByUser
属性的信息。
这是我使用集合视图的委托方法加载每个单元格的方法:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ObjectCell", for: indexPath) as! ObjectCell
cell.configureCell(
isLikedByUser: objects[indexPath.row].isLikedByUser!,
numOfLikes: objects[indexPath.row].numOfLikes!,
)
return cell
}
ObjectCell类具有以下三个字段:
var isLikedByUser: Bool?
@IBOutlet weak var numOfLikes: UILabel!
@IBOutlet weak var likeBtn: UIButton!
属于该单元格类的configureCell()
方法在这里:
public func configureCell(numOfLikes: Int, isLikedByUser: Bool) {
self.isLikedByUser = isLikedByUser
self.numOfLikes.text = String(numOfLikes)
if isLikedByUser {
self.likeBtn.setFATitleColor(color: UIColor.cyan, forState: .normal)
} else {
self.likeBtn.setFATitleColor(color: UIColor.white, forState: .normal)
}
}
最后,prepareForReuse()
方法在这里:
override func prepareForReuse() {
if isLikedByUser! {
self.likeBtn.setTitleColor(UIColor.cyan, for: .normal)
} else {
self.likeBtn.setTitleColor(UIColor.white, for: .normal)
}
}
这不起作用。即使这样做,我仍然不知道一种方法来防止numOfLikes
标签递减或是否应该递减。我推测此问题的很大一部分是我没有正确使用prepareForReuse()
方法...感谢您的帮助,谢谢。
答案 0 :(得分:1)
prepareForReuse
不是修改单元格的地方,顾名思义,您“仅”必须准备它以供重用。如果您更改了某些内容(例如视图的isHidden
属性),则只需将它们更改回初始状态。
尽管应该做的是,您可以在单元格内为didSet
实现isLikedByUser
,并将修改应用于其中的likeBtn。 (这当然是快速的解决方案)
长期解决方案:这是一种反模式,您的单元格具有一个名为isLikedByUser
的属性,TableViewCell是一个View,在所有体系结构中,对于业务逻辑,View应该尽可能地愚蠢。正确的方法是将这些修改应用于在ViewController中实现的configure-cell方法。
如果您觉得您将在不同的viewControllers中大量使用此单元格,则至少要通过协议对其进行定义,并通过该协议与您的单元格对话。这样,您将拥有更可重用和可维护的代码。
答案 1 :(得分:0)
当前所有这些都很好,唯一缺少的部分是单元重用,您必须向模型数组反映点赞次数的变化
class ObjectCell:UICollectionViewCell {
var myObject:LikableObject!
}
在cellForRowAt
cell.myObject = objects[indexPath.row]
现在在单元格自定义类中,您可以使对象反映对它的任何更改,确保可以使用委托/回调或任何观察技术
答案 2 :(得分:0)
这里不需要prepareForResuse
。
您确实需要更新表格视图下的模型。一种验证方法是使用预先喜欢的模拟数据,然后查看该数据是否正确显示。