Cao Dongping
Cao Dongping

Reputation: 989

UICollectionView reloadData But View Blinks

I have an UICollectionView and a custom UICollectionViewCell to display my content, which should be refreshed every second.

I am going to invoke reloadData method to reload the whole collection view to fit my needs.

But, but, My collection view cell blinks every time I reload data.

It seems like the image below. Two seconds of my app. The first second is OK. But second second, the collection view display reused cell first (yellow area) and then display the correct cell(configured cell) finally. Which looks like a blink.

enter image description here

It seems like a cell-reuse issue. CollectionView displays cells without completely finish configure it. How could I fix it?

My cellForItemAtIndexPath: method:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    YKDownloadAnimeCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:[YKDownloadAnimeCollectionCell description] forIndexPath:indexPath];

    YKAnimeDownloadTask *animeDownloadTask = [[YKVideoDownloadTaskManager shared] animeDownloadTasks][indexPath.row];
    [cell setUpWithDownloadAnime:animeDownloadTask editing:self.vc.isEditing];
    cell.delegate = self;

    if (self.vc.isEditing) {
        CABasicAnimation *imageViewAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
        imageViewAnimation.fromValue = @(-M_PI/64);
        imageViewAnimation.toValue = @(M_PI/128);
        imageViewAnimation.duration = 0.1;
        imageViewAnimation.repeatCount = NSUIntegerMax;
        imageViewAnimation.autoreverses = YES;
        [cell.coverImageView.layer addAnimation:imageViewAnimation forKey:@"SpringboardShake"];

        CABasicAnimation *deleteBtnAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
        deleteBtnAnimation.fromValue = @(-M_PI/32);
        deleteBtnAnimation.toValue = @(M_PI/32);
        deleteBtnAnimation.duration = 0.1;
        deleteBtnAnimation.repeatCount = NSUIntegerMax;
        deleteBtnAnimation.autoreverses = YES;
        [cell.deleteBtn.layer addAnimation:deleteBtnAnimation forKey:@"SpringboardShake1"];
    } else {
        [cell.coverImageView.layer removeAllAnimations];
        [cell.deleteBtn.layer removeAllAnimations];
    }

    return cell;
}

Upvotes: 10

Views: 10647

Answers (3)

diegomercado
diegomercado

Reputation: 184

You can do the following:

UIView.performWithoutAnimation {
    self.collectionView.performBatchUpdates({
        self.collectionView.reloadData()
    }, completion: nil)
}

Upvotes: 1

Arman Momeni
Arman Momeni

Reputation: 680

Well I found the answer though it's been so long from the question.

Don't use reloadData() nor reloadItems().

Use collectionView.reloadSections(IndexSet(integer: yourSectionIndex)). The animation will happen smoothly.

Upvotes: 14

LembergSun
LembergSun

Reputation: 661

self.collectionView.reloadItems(at: self.collectionView.indexPathsForVisibleItems)

Helped for me.

Upvotes: 11

Related Questions