Ios UICollectionView单元重用性问题

Ios UICollectionView单元重用性问题,ios,uicollectionview,gallery,Ios,Uicollectionview,Gallery,我正在制作一个简单的gallery iOS程序,对UICollectionView数据源行为有一个问题 在我的代码中,除了当我向上或向下滚动时,每个单元格的图像都会闪烁之外,一切都正常 不可见单元在图像可见之前不会下载图像。 在我的代码中,它是按需下载的。这是最佳实践吗?这就是我得到闪烁的细胞的原因吗 我对细胞的可重用性感到困惑。根据我的观察,当一个细胞变得不可见时,它就失去了自己的形象。我怎样才能防止这种情况?这也是我得到闪烁细胞的原因吗 这是代码 - (UICollectionViewCel

我正在制作一个简单的gallery iOS程序,对UICollectionView数据源行为有一个问题

在我的代码中,除了当我向上或向下滚动时,每个单元格的图像都会闪烁之外,一切都正常

  • 不可见单元在图像可见之前不会下载图像。 在我的代码中,它是按需下载的。这是最佳实践吗?这就是我得到闪烁的细胞的原因吗

  • 我对细胞的可重用性感到困惑。根据我的观察,当一个细胞变得不可见时,它就失去了自己的形象。我怎样才能防止这种情况?这也是我得到闪烁细胞的原因吗

  • 这是代码

    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    
            FBPhotoCollectionViewCell *cell = (FBPhotoCollectionViewCell*)[collectionView dequeueReusableCellWithReuseIdentifier:@"PhotoCell" forIndexPath:indexPath];
    
            __weak FBPhotosVC *weakSelf = self;
    
            if ([_PhotoLinks count] > 0) {
                   dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    
    
            NSURL* theURL = [NSURL URLWithString:[_PhotoLinks objectAtIndex:(int)indexPath.row]];
            UIImage* tempImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:theURL]];
    
            if ([weakSelf.theCollectionView.indexPathsForVisibleItems containsObject:indexPath]) {
    
                if (tempImage)
                {
                    dispatch_async(dispatch_get_main_queue(), ^{
                        FBPhotoCollectionViewCell *cell = (FBPhotoCollectionViewCell *)[weakSelf.theCollectionView cellForItemAtIndexPath:indexPath];
                        cell.theImageView.image = tempImage;
                    });
                }
                else
                {
                    // Download failed.
                    NSLog(@"Downloaded image is nil.");
                }
            }
        });
    }
    
    cell.backgroundColor = [UIColor grayColor]; <br>
    return cell; <br>
    }
    
    -(UICollectionViewCell*)collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath:(NSIndexPath*)indexPath{
    FBPhotoCollectionViewCell*单元格=(FBPhotoCollectionViewCell*)[collectionView dequeueReusableCellWithReuseIdentifier:@“PhotoCell”forIndexPath:indexPath];
    __弱FBVC*weakSelf=self;
    如果([\u照片链接计数]>0){
    调度异步(调度获取全局队列(调度队列优先级默认为0)^{
    NSURL*theURL=[NSURL-URLWithString:[[u PhotoLinks objectAtIndex:(int)indexath.row]];
    UIImage*tempImage=[UIImage imageWithData:[NSData dataWithContentsOfURL:theURL]];
    if([weakSelf.theCollectionView.indexPathsForVisibleItems包含对象:indexPath]){
    如果(临时图像)
    {
    dispatch\u async(dispatch\u get\u main\u queue()^{
    FBPhotoCollectionViewCell*单元格=(FBPhotoCollectionViewCell*)[weakSelf.theCollectionView单元格for ItemAtIndexPath:indexPath];
    cell.theImageView.image=tempImage;
    });
    }
    其他的
    {
    //下载失败。
    NSLog(@“下载的图像为零”);
    }
    }
    });
    }
    cell.backgroundColor=[UIColor grayColor];
    返回单元格;
    }
    尝试删除以下内容:

    if ([weakSelf.theCollectionView.indexPathsForVisibleItems containsObject:indexPath]) 
    
    您不必检查单元格是否可见。cellForItemAtIndexPath仅在新单元格可见时调用,当该单元格从屏幕上消失时,它将被重用

    另外,我不认为您真的需要多线程来加载这样的图像。试着把它拆两下

    您可以将已下载的图像存储在数组或字典中,并在每次调用cellForItemAtIndexPath时进行检查

    (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {
        FBPhotoCollectionViewCell cell = (FBPhotoCollectionViewCell)[collectionView dequeueReusableCellWithReuseIdentifier:@"PhotoCell" forIndexPath:indexPath];
    
        if ([_PhotoLinks count] > 0) 
        { 
            NSString photoName = [_PhotoLinks objectAtIndex:(int)indexPath.row];
            UIImage* tempImage = [self.cacheDictionnary objectForKey:photoName];
    
            if (!tempImage)
            {
                NSURL* theURL = [NSURL URLWithString:photoName];
                tempImage= [UIImage imageWithData:[NSData dataWithContentsOfURL:theURL]];
            }
    
            if (tempImage)
            {
                [self.cacheDictionnary setObject:tempImage forKey:photoName];
                cell.theImageView.image = tempImage;
            }
            else
            {
                // Download failed.
                NSLog(@"Downloaded image is nil.");
            }
        }
    
        cell.backgroundColor = [UIColor grayColor];
        return cell;
    }
    
    TrainingGoalsCell单元格=(TrainingGoalsCell)[collectionView dequeueReusableCellWithReuseIdentifier:@“cell”forIndexPath:indexPath]

    NSString *thePath=[[NSBundle mainBundle] pathForResource:[arrayVideos objectAtIndex:indexPath.row] ofType:@"mp4"];
    NSURL *url = [NSURL fileURLWithPath:thePath];
    
    
    
    CGRect attachmentFrame = CGRectMake(2, 2, cell.frame.size.width-4, cell.frame.size.height-4);
    
    if(!isScrolling){
    UIView* subView;
    // asset is a video
        self.avPlayer = [[AVPlayer alloc] initWithURL:url];
        self.avPlayer.muted = YES;
        self.avPlayerLayer =[AVPlayerLayer playerLayerWithPlayer:self.avPlayer];
        [self.avPlayerLayer setFrame:CGRectMake(0, 0, cell.frame.size.width-4, cell.frame.size.height-4)];
    
        if(!subView){
        subView = [[UIView alloc]initWithFrame:attachmentFrame];
        [subView.layer addSublayer:self.avPlayerLayer];
        [[cell.contentView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
        [cell.contentView addSubview:subView];
        }
    
        [self.avPlayer seekToTime:kCMTimeZero];
        self.avPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
        [self.avPlayer play];
    
        self.avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
    
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemDidReachEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:[self.avPlayer currentItem]];
    }