Я работаю над приложением, которое имеет UICollectionView
с бесконечной прокруткой.Каждая ячейка имеет кнопку «Нравится».Проблема в том, что чем меньше я прокручиваю, тем медленнее кнопка «Мне нравится» меняет свой цвет при нажатии.
Это может занять до 3 секунд между print("BEGIN")
и print("END")
в моем коде.Я также заметил, что 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
}
}
ОБНОВЛЕНИЕ:
Трассировка стека при помещении точки останова в метод didSet
: