【问题标题】:UICollectionView initial scroll lag?UICollectionView 初始滚动滞后?
【发布时间】:2015-01-28 19:44:46
【问题描述】:

我使用UICollectionView 类设置了3x18“网格视图”。每个单元格都包含一个从NSDictionary 加载的UIImageView。共有 18 张图片,总计约“20 MB”。

我遇到的问题是当我最初在视图中时,我从顶部滚动到底部,它很滞后。之后,滚动就像照片应用一样流畅。

为什么会这样?是不是因为我的图片太大了?

这是我的代码:

- (void)viewDidLoad

{
    [super viewDidLoad];

    dictionary = @{@"01"    : @[@"Image 1"],
                   @"02"    : @[@"Image 2"],
                   // etc etc 
                  };

    numOfImages = [ [dictionary allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

    // Allows appropriate methods to be used
    self.pageantCollectionView.delegate = self;
    self.pageantCollectionView.dataSource = self;
}

// Populate each cell with specified data

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

{
    CustomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];

    NSString *number = [numOfImages objectAtIndex:indexPath.row];

    NSArray *imageByNumber = [dictionary objectForKey:number];

    NSString *name= [imageByNumber objectAtIndex:indexPath.section];

    cell.nameLabel.text = name;

    cell.imageView.image = [UIImage imageNamed:[self getImage:name] ];

    // Set rounded corners
    CALayer * l = [cell.imageView layer];

    [l setMasksToBounds:YES];

    [l setCornerRadius:10.0];

    return cell;
}

- (void)collectionView:(UICollectionView *)colView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath {

    UICollectionViewCell* cell = [colView cellForItemAtIndexPath:indexPath];

    CALayer * l = [cell layer];

    [l setMasksToBounds:YES];

    [l setCornerRadius:10.0];

    cell.contentView.backgroundColor = [UIColor lightGrayColor];

}

- (void)collectionView:(UICollectionView *)colView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath 
{
    UICollectionViewCell* cell = [colView cellForItemAtIndexPath:indexPath];
    cell.contentView.backgroundColor = nil;    
}

这是否与我在cellForItemAtIndexPath 内动态设置“imageView”的角半径以及didHighlightItemAtIndexPath 内单元格本身的角半径这一事实有关?

如果是这样,我该如何为“imageView”和“cell”本身静态创建圆角半径?

谢谢

【问题讨论】:

    标签: ios objective-c uicollectionview uicollectionviewcell


    【解决方案1】:

    延迟更可能是使用[UIImage imageNamed:] 加载图像第一次,这些是从磁盘加载的(慢)。随后它们将从内存缓存中加载,这将很快。你会得到一个更糟糕的结果,你的图像越大。

    注意事项

    • 与视图大小相比,您的图像有多大(以像素为单位)?如果它们大得多,您应该考虑提供显示尺寸的缩略图版本。

    • 预加载。应用程序中是否有更好的地方来产生这种延迟?例如在启动期间(在显示 collectionView 之前?如果是这样,请尝试将它们全部(使用 imageNamed:)加载到 NSDictionaryNSCache 中(这就像在内存不足的情况下被刷新的字典)

    • 异步加载。考虑改用UIImage imageFromContentsOfFile:,您可以将其放入后台线程(然后将图像加载到主线程上的imageView中)。与imageNamed 不同,此方法不缓存,但您可以通过将结果添加到NSCache 来手动执行此操作。您需要编写一些代码,以便在可用时从缓存中获取图像,而不是从磁盘重新获取它。
      可能可以使用imageNamed 执行此操作 - 但它不是线程安全的,因此您不应该真正尝试它(请参阅this answer 旁边的 cmets)。

    • 可能在主线程上显示图像之前强制在后台线程上进行初始屏幕外绘制。这会强制图像在后台解压缩。您需要结合前一种技术来试验这种技术,看看它是否真的对您有所帮助。

    • 单元初始化。任何只需要在单元格上发生一次的事情,都不应该在cellForItem... 中完成。正如 Daniel Shaffer 建议的那样,您可以将这些东西(例如您的单元格层角半径)移动到单元格 init 方法中。无论如何,您都应该这样做,尽管我认为这不是您当前滚动问题的主要原因。

    【讨论】:

    • 1. 2x 图像:827 x X,3x 图像:1242 x Y......2。哪个更好? NSDictionary 还是 NSCache?....3。我有点明白你的意思,但你能给我举个例子吗?谢谢
    • @Pangu... 1/ 我不明白你的数字。如果您的单元格图像视图是(例如)100 x 100 pts,那么您的 2x 图像是多少? 200x200px 是正确的:如果更大,您应该提供正确大小的缩略图 2/NSCache 是正确的存储对象。 3/ 这里有一个old answer of mine 可能会有所帮助
    • 抱歉,我以为您指的是我使用的实际图像。单元格图像大小仅为 100x150。我可以将实际图像调整为该大小,但我将在另一个视图控制器中以更大的尺寸使用这些图像,因此拥有相同图像的 2 个版本效率不高(我不认为)。
    【解决方案2】:

    创建一个自定义UICollectionViewCell,并在awakeFromNib 方法中的单元格子类中设置角半径和其他任何内容。这是为了防止它每次都修改图层(就像它目前通过cellForItem 方法所做的那样)。

    即:

    CustomCell *cell = (CustomCell*)[colView cellForItemAtIndexPath:indexPath];
    

    还要确保在viewDidLoad 中注册单元格(您可以在各处找到自定义单元格指南)。

    【讨论】:

    • CustomCell cell = (CustomCell)[colView cellForItemAtIndexPath:indexPath] 去哪儿了?对不起..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-29
    • 2018-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多