【问题标题】:UICollectionView cell reusability issuesUICollectionView 单元格可重用性问题
【发布时间】:2015-10-29 09:11:00
【问题描述】:

我正在制作一个简单的图库 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>
}

【问题讨论】:

    标签: ios uicollectionview gallery


    【解决方案1】:

    尝试删除它:

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

    【讨论】:

      【解决方案2】:

      TrainingGoalsCell cell = (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]];
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-06-14
        • 1970-01-01
        • 1970-01-01
        • 2017-05-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多