UICollectionView跳转滚动

时间:2015-03-20 11:28:43

标签: ios objective-c scroll uicollectionview uicollectionviewcell

我正在尝试创建一个可以保存不同大小的“视图”的界面等。为此,我使用了这些单元格的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问题。根据我的阅读,这与滚动期间重新加载单元格有关。什么是防止这种情况的正确方法?

非常重要的是要注意内容是动态的。用户应该能够在运行时添加和删除卡。

由于

4 个答案:

答案 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)

我有点想通了。我的一些卡包含图像,每次我滚动系统都会从内存中重新加载所有这些图像。这使得滚动相对缓慢且不连贯。