我正在处理一个具有无限卷轴UICollectionView
的应用。每个单元格都有一个类似按钮。问题是我滚动的越低 - 类似按钮在点击时改变颜色的速度越慢。
我的代码中print("BEGIN")
和print("END")
之间最多可能需要3秒钟。我还观察到,print(post)
被调用了几十次,并打印了几十个帖子,我没有按下这样的按钮。我希望它只能在我正在更新的单元格中调用didSet
。
有人可以解释为什么它似乎在多个单元格中调用didSet而不是仅仅调用了一个单元格?是否与重复使用的细胞有关?
你如何解决这个长时间延迟问题?我希望单元格将按钮图像更新为选定的按钮图像而不会有太长的延迟。
protocol HomePostCellDelegate {
func didTapLike(for cell: HomePostCell)
}
class HomePostCell: UICollectionViewCell {
var delegate: HomePostCellDelegate?
var post: Post? {
didSet {
print(post)
likeButton.setImage(post?.isLiked == true ? #imageLiteral(resourceName: "like_selected").withRenderingMode(.alwaysTemplate) : #imageLiteral(resourceName: "like_unselected").withRenderingMode(.alwaysTemplate), for: .normal)
likeButton.tintColor = .white
// ...
}
}
lazy var likeButton: UIButton = {
let button = UIButton(type: .system)
button.setImage(#imageLiteral(resourceName: "like_unselected").withRenderingMode(.alwaysOriginal), for: .normal)
button.addTarget(self, action: #selector(handleLike), for: .touchUpInside)
return button
}()
@objc func handleLike() {
NSLog("@objc func handleLike()")
delegate?.didTapLike(for: self)
}
// ...
}
class HomeController: UICollectionViewController, UICollectionViewDelegateFlowLayout, HomePostCellDelegate {
// ...
func didTapLike(for cell: HomePostCell) {
let generator = UIImpactFeedbackGenerator(style: .light)
generator.impactOccurred()
guard let indexPath = collectionView?.indexPath(for: cell) else { return }
guard let post = cell.post else { return }
cell.post.isLiked = !cell.post.isLiked
if cell.post.isLiked {
cell.post.numberOfLikes += 1
} else {
cell.post.numberOfLikes -= 1
}
print("BEGIN")
self.collectionView?.reloadItems(at: [indexPath])
print("END")
}
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if indexPath.item == self.presenter.posts.count - 5 && !presenter.isFinishedPaging && !presenter.isCurrentlyPaging {
presenter.isCurrentlyPaging = true
presenter.paginatePosts(withSuccess: { [weak self] () in
self?.collectionView?.refreshControl?.endRefreshing()
self?.collectionView?.reloadData()
self?.presenter.isCurrentlyPaging = false
}) { [weak self] (errorMessage) in
self?.presenter.isCurrentlyPaging = false
print(errorMessage)
}
}
if presenter.posts.count == 0 {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: errorCellId, for: indexPath) as! ErrorCell
setUpErrorCellAnimation(cell: cell)
return cell
} else if presenter.posts[indexPath.item].id == nil {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: adCellId, for: indexPath) as! AdCell
// some ad logic here
// ...
cell.contentView.addSubview(bannerView)
return cell
} else {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! HomePostCell
cell.delegate = self
if presenter.isAdmin && presenter.isInAdminView {
cell.isInAdminView = true
} else {
cell.isInAdminView = false
}
cell.post = presenter.posts[safe: indexPath.item]
return cell
}
}
更新: