我正在尝试创建一个可以保存不同大小的“视图”的界面等。为此,我使用了这些单元格的UICollectionView:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
Card *card = [[[usermanager getSelectedUser] getCards] objectAtIndex:indexPath.item];
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:@"cardCell" forIndexPath:indexPath];
[cell addSubview:card];
[cell.layer setBorderColor:[UIColor redColor].CGColor];
[cell.layer setBorderWidth:1.0f];
[cell.layer setMasksToBounds:NO];
return cell;
}
Everthing似乎工作得很好,直到卡的数量变得太大而我必须滚动。滚动后抬起手指时,视图会跳跃一点。我得到了一些其他奇怪的UI问题。根据我的阅读,这与滚动期间重新加载单元格有关。什么是防止这种情况的正确方法?
非常重要的是要注意内容是动态的。用户应该能够在运行时添加和删除卡。
由于
答案 0 :(得分:2)
您在评论中说明您使用的是CHTCollectionViewWaterFallLayout
。
我自己在一个应用程序中使用它,从性能的角度来看,它不是最优的(我现在检查了源代码,关键点仍然是相同的)。我不得不做几次调整才能顺利完成。
首先,如果你的目标是 iOS 8及以上,那么UICollectionView
已经有了很大的改进,如果可能的话,你绝对应该确保使用它。 2014年WWDC视频What's New in Table and Collection Views为您提供了一个很好的概述。关键是iOS 8为UICollectionViewLayoutInvalidationContext
添加了三种新方法:
- invalidateItemsAtIndexPaths:
- invalidateSupplementaryElementsOfKind:atIndexPaths:
- invalidateDecorationElementsOfKind:atIndexPaths:
将这些方法与UICollectionViewLayout invalidationContextForBoundsChange:
一起使用,可以极大地缩小布局需要处理的项目数量。这将为您提供最佳性能。
如果像我一样,你还需要定位 iOS 7 ,事情会变得更加复杂。您可以在布局中使用两种关键方法来改进:
shouldInvalidateLayoutForBoundsChange:
调查更改的边界,并确保仅在绝对必要时使整个布局无效。prepareLayout
,只有在完整布局失效时才应调用。{/ li>
在我的情况下,我必须添加浮动标题,因此我在shouldInvalidateAll
中设置了一个属性shouldInvalidateLayoutForBoundsChange:
,我在prepareLayout
检查了一下,知道我是否真的需要准备布局从头开始。
实际上并不那么容易(但可能)让它顺利进行,但我希望这为你的版本提供了一个改进的起点。
答案 1 :(得分:1)
您可以创建集合视图单元的子类,并在创建它时执行所有图层初始化,而不是每次重复使用时。
此外,重新使用此类单元格时,应检查现有单元格是否已添加Card
。重用时,iOS并不会自动删除添加的子视图(因此对于重用的单元格,addSubview可以使用不同的卡执行多次,您可以通过查看调试来检查)。
您也可以延迟加载单元格内容。
答案 2 :(得分:1)
正如我从您的代码中可以理解的那样,在每个cellForItemAtIndexPath调用中,您正在创建一个新的卡对象并将其作为子视图添加到单元格上。
您实际上并没有使用重复使用细胞的能力。 尝试在单元格上添加UI元素(故事板或xib,无论您使用什么)。然后根据索引路径设置这些元素的值。这将消除滚动的滞后。
还导入<QuartzCore/QuartzCore.h>
[cell.layer setShadowPath:[[UIBezierPath
bezierPathWithRect:self.bounds] CGPath]];
[cell.layer setBorderColor:[UIColor redColor].CGColor];
[cell.layer setBorderWidth:1.0f];
[cell.layer setMasksToBounds:NO];
答案 3 :(得分:1)
我有点想通了。我的一些卡包含图像,每次我滚动系统都会从内存中重新加载所有这些图像。这使得滚动相对缓慢且不连贯。