滚动时收集视图图像闪烁

时间:2016-06-07 04:24:13

标签: ios objective-c uicollectionview

我使用以下代码用图像填充集合视图单元格。

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *identifier = @"Cell";

    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];

    UIImageView *recipeImageView = (UIImageView *)[cell viewWithTag:100];
    recipeImageView.image = nil;
    if ([imageArray count] >0){

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) {
            NSData *data0 = [NSData dataWithContentsOfURL: [NSURL URLWithString:[imageArray objectAtIndex:indexPath.row]]];
            UIImage *image = [UIImage imageWithData: data0];

            dispatch_sync(dispatch_get_main_queue(), ^(void) {
                recipeImageView.image = image;
            });
        });

    }

    [spinnerShow stopAnimating];


    return cell;
}

问题在于,当我滚动图像时闪烁并闪烁。为什么会这样?如何在不闪烁的情况下使这些图像稳定?

2 个答案:

答案 0 :(得分:1)

根据我的知识,你正在获取图像,但没有缓存它,这就是为什么当你的UICollectionViewCell重新加载时,你得到了UIImageView的新实例,所以这个东西在你的代码中继续......

在这种情况下,我建议您使用SDWebImageAFNetworking框架。因为这些框架使用简单的代码行(SDWebImage Framework)为您完成了所有棘手的工作,

NSURL* url = [NSURL URLWithString:str];
    [yourImageView setBackgroundImageWithURL:url forState:UIControlStateNormal placeholderImage:kPlaceholder];

答案 1 :(得分:1)

只是简短的概述,所以你得到答案

UICollectionView经过高度优化,因此只在内存中保留屏幕上可见的行。现在,所有行单元格都缓存在池中并被重用而不是重新生成。每当用户滚动UICollectionView时,它会在Pool中添加刚刚隐藏的行,并重新使用它们作为可见行。

所以,现在,回答你的问题

当您滚动CollectionView时,会为每个indexPath再次调用collectionView数据源方法,进入可见范围并再次下载您的图像

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

<强>解

在方法之外实例化一个实例NSMutableDictionary。

现在在你的代码中

@implementation ClassName{
  NSMutableDictionary *cachedImage;
}

-(void)viewDidLoad(){
  [super viewDidLoad];
  cachedImage = [NSMutableDictionary new];
}

/*OLD CODE*/
UIImageView *recipeImageView = (UIImageView *)[cell viewWithTag:100];
    recipeImageView.image = nil;

    if ([imageArray count] >0){
    //IF image is already downloaded, simply use it and don't download it.
       if(cachedImage[[imageArray objectAtIndex:indexPath.row]] != nil){
     recipeImageView.image = cachedImage[[imageArray objectAtIndex:indexPath.row]];
}
else{

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) {
            NSData *data0 = [NSData dataWithContentsOfURL: [NSURL URLWithString:[imageArray objectAtIndex:indexPath.row]]];
            UIImage *image = [UIImage imageWithData: data0];

            dispatch_sync(dispatch_get_main_queue(), ^(void) {
                recipeImageView.image = image;
                //****SAVE YOUR DOWNLOADED IMAGE 
                cachedImage[[imageArray objectAtIndex:indexPath.row]] = image; //****SAVE YOUR DOWNLOADED IMAGE 
            });
        });
}


    }


/*OLD CODE*/