CollectionView reloadItems(at :)在多个单元格中调用didSet()

时间:2018-05-24 03:32:47

标签: ios swift uicollectionview uibutton

我正在处理一个具有无限卷轴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
    }
}

更新:

didSet方法中放置断点时的堆栈跟踪: enter image description here

0 个答案:

没有答案