繁体   English   中英

UICollectionView单元可重用性问题

[英]UICollectionView cell reusability issues

我正在制作一个简单的Gallery iOS程序,并对UICollectionView数据源行为有疑问。

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

  1. 不可见的单元格在可见之前不会下载图像。 在我的代码中,它是按需下载的。 这是最佳做法吗? 这是为什么我的细胞闪烁的原因吗?

  2. 细胞的可重用性让我感到困惑。 根据我的观察,当细胞变得不可见时,它会丢失其自身的图像。 我该如何预防? 这也是我细胞闪烁的原因吗?

这是代码。

- (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>
}

尝试删除此:

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 cell =(TrainingGoalsCell )[collectionView dequeueReusableCellWithReuseIdentifier:@“ Cell” for IndexPath: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]];
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM