在集合视图中滚动时,按钮和标签会重置

时间:2018-07-30 19:04:22

标签: ios swift xcode uicollectionview uicollectionviewcell

我有一个收集视图,其中每个单元格都具有与用户进行交互的能力。每个单元格都有一个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将为每个单元格返回numOfLikesisLikedByUser属性的信息。

这是我使用集合视图的委托方法加载每个单元格的方法:

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()方法...感谢您的帮助,谢谢。

3 个答案:

答案 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

您确实需要更新表格视图下的模型。一种验证方法是使用预先喜欢的模拟数据,然后查看该数据是否正确显示。