UICollectionview加载单元格时滚动波动

时间:2013-08-27 08:31:51

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

我的应用中有一个使用UICollectionView的图库。细胞大小约为70,70。我使用的是库中ALAssets的{​​{1}},我已将其存储在列表中。

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

ALAssetLibrary

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

我希望用户界面像股票应用程序一样黄油。

我现在怀疑-(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; } 可能会阻碍UICollectionViewCell prepareForReuse方法,但使用我无法找到的工具。

可能造成这种情况的任何其他事情?是否有“更快”的方式以更快的方式准备dequeueReusableCellWithReuseIdentifierUICollectionViewCell

7 个答案:

答案 0 :(得分:95)

任何有滚动问题的人都应该this

在您出队后添加这两行

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

答案 1 :(得分:19)

我认为“波动性”来自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

答案 2 :(得分:8)

使用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]];
}];

答案 3 :(得分:2)

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

答案 4 :(得分:0)

我遇到了UICollectionView滚动问题。

对我来说(几乎)有点像魅力:我用png缩略图90x90填充了单元格。我说几乎是因为第一个完整的卷轴不是那么顺利,但是再也没有崩溃......

就我而言,单元格大小为90x90。

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

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

答案 5 :(得分:0)

如果有人使用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!
    })

答案 6 :(得分:0)

我将分享使用集合视图的经验。

快速5

如果您正在运行 iOS 10 + ,性能应该已经比以前的iOS版本更好。我强烈建议您观看此WWDC视频-What's New in UICollectionView in iOS 10

提高性能的一个非常简单的事情就是实现 prefetching 委托。我实际上只是执行它而已!

  • 首先请确保您的collectionView符合委托,

    yourCollectionView.prefetchDataSource = self
    
  • 然后只实现预取委托,

    extension YourViewController: UICollectionViewDataSourcePrefetching {
        func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) {
            // You could do further optimizations here.
        }
    }