【问题标题】:UICollectionview Scrolling choppy when loading cells加载单元格时UICollectionview滚动不连贯
【发布时间】:2013-08-29 22:02:28
【问题描述】:

我的应用中有一个使用UICollectionView 的图库。细胞大小约为 70,70。我在存储在列表中的画廊中使用来自ALAssetLibraryALAssets

我正在使用通常的模式来填充单元格:

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

  mycell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
  mycell.imageView.image = [[UIImage imageWithCGImage:[alassetList objectAtIndex:indexpath.row] thumbnail]];
  return mycell;
}

我的画廊滚动不连贯。我不明白为什么会这样。我尝试添加一个 NSCache 来缓存缩略图图像(认为创建图像可能很昂贵)但这对性能没有帮助。

我希望 UI 与股票应用程序一样流畅。

我现在怀疑它可能是 UICollectionViewCell prepareForReuse 中的某些东西,它可能阻碍了 dequeueReusableCellWithReuseIdentifier 方法,但使用我无法找到的工具。

还有其他可能导致此问题的原因吗?有没有“更快”的方式来准备UICollectionViewCelldequeue 他们以更快的方式?

【问题讨论】:

  • 使用工具,你有没有发现一个方法调用花费了太多时间?例如。 0.02 秒重复使用一个单元格对于平滑滚动来说太长了。
  • 是的。在这样做之后,我看到方法 [uicollectionview updatevisiblecellsnow] 被调用了很多次。谷歌搜索了这个问题并得到了这个问题stackoverflow.com/questions/16336772/…
  • 尝试将单元格的一些与显示相关的函数移动到集合视图的 willDisplayCell 方法,将其他的移动到 didEndDisplayingCell 方法。
  • 这是我最新的完美平滑滚动集合视图,带有实时视频预览(一次最多 16 个:youtu.be/7QlaO7WxjGg 它甚至使用封面流自定义布局和“反射”视图完美反映视频预览。源代码在这里:mediafire.com/download/ivecygnlhqxwynr/…

标签: ios objective-c uicollectionview uicollectionviewcell xcode-instruments


【解决方案1】:

所以任何有滚动问题的人都应该这样做this

在出队后添加这两行

cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;

【讨论】:

  • 对不起,我该怎么办?您的链接指向一个包含大量内容的页面。如果我有 ++any++ 滚动问题,我应该阅读所有内容吗?或者只是如果它是滞后的?
  • 我不确定您的问题到底是什么。您可以向我指出您的问题,但在我的情况下,事实证明 UICollectionView 导致了滞后,而我的代码实际上表现良好。在我的情况下,强制单元层栅格解决了这个问题。在其他情况下,您可以尝试使用 XCode 中的 Time Instument 来了解缓慢。如果是您的代码或某些系统代码。
  • @AvnerBarr 感谢您的精彩回答,以及您对另一个问题的回答stackoverflow.com/questions/16336772 我已经添加了一个小赏金来表示感谢大家:) 干杯
  • 但我不会在单元格本身中设置该属性,因为光栅化具有您可能不一定想要的内存/性能影响。但正如其他人在这里以各种形式提到的那样,主要的性能损失源于系统在主线程上解压缩 UIImage [UIImage image...]。这对大图像来说代价高昂(检查新的 iOS-8 api for PHImageManager 可以提供帮助)。在最坏的情况下,我建议在将图像分配给 UIImageView 之前在后台线程上强制解压缩图像
  • 根据我的观察,这会导致单元格上出现更多滞后(使用 PHCachingManager),最好的解决方案是在设置图像后在图像视图上设置光栅化(这很重要),滞后几乎消失了(也使用了苹果示例中的 startCaching)。
【解决方案2】:

UICollectionView 滚动时遇到问题。

什么对我来说(几乎)像是一种魅力:我用 90x90 的 png 缩略图填充了单元格。我说差不多是因为第一次完整的滚动不是那么流畅,但再也没有崩溃过......

在我的例子中,单元格大小是 90x90。

我之前有很多原始 png 大小,当 png 原始大小大于 ~1000x1000 时,它非常不稳定(第一次滚动时很多崩溃)。

所以我在UICollectionView 上选择 90x90(或类似)并显示原始 png(无论大小)。希望这对其他人有帮助。

【讨论】:

    【解决方案3】:

    使用 NSURLConnection 的 sendAsynchronousRequest:queue:completionHandler: 加载图片

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
        [cell.imageView setImage:[UIImage imageWithData:data]];
    }];
    

    【讨论】:

      【解决方案4】:

      我会假设“断断续续”来自 UIImage 分配,而不是 dequeueReusableCellWithReuseIdentifier 方法。我会尝试在后台线程上进行图像分配,看看这是否会让事情变得更简单。

      -(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
      {
        mycell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
      
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) {
           // Load image on a non-ui-blocking thread
          UIImage *image = [[UIImage imageWithCGImage:[alassetList objectAtIndex:indexpath.row] thumbnail]];
      
          dispatch_sync(dispatch_get_main_queue(), ^(void) {
              // Assign image back on the main thread
              mycell.imageView.image = image;
          });
        });
      
        return mycell;
      }
      

      更多详情可以在这里找到:https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/Introduction/Introduction.html

      【讨论】:

      • 稍微平滑一点,并为其添加自定义视图。如果像你这样的东西尝试在集合视图中显示
      【解决方案5】:

      在属性检查器中勾选剪辑子视图和不透明,并勾选启用分页。

      【讨论】:

        【解决方案6】:

        如果有人在使用 PhImageManager,关闭同步可以解决问题。 (deliveryMode = .FastFormat 还可以提供额外的性能增强,但权衡是缩略图的质量会降低)

            let option = PHImageRequestOptions()
            option.deliveryMode = .Opportunistic
            option.synchronous = false
            PHImageManager().requestImageForAsset(phAsset, targetSize: CGSizeMake(2048, 2048), contentMode: .AspectFit, options: option, resultHandler: { (image, objects) in
                self.imageView.image = image!
            })
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多