scrollToItemAtIndexPath 破坏 UICollectionViewCell 布局

Posted

技术标签:

【中文标题】scrollToItemAtIndexPath 破坏 UICollectionViewCell 布局【英文标题】:scrollToItemAtIndexPath destroys UICollectionViewCell layout 【发布时间】:2014-11-15 15:24:30 【问题描述】:

我正在创建一个水平滚动的分页 UICollectionView,其单元格与集合视图一样大,因此一次只显示一个单元格。我还想在集合视图首次出现时首先显示最后一个项目,以便从左侧显示其他项目,而不是从右侧显示下一个项目的默认值。

为此,我按照this answer 的建议在视图控制器的viewDidLayoutSubviews 中调用scrollToItemAtIndexPath:。如果我在 viewWillAppear 或 viewDidLoad 中调用scrollToItemAtIndexPath,则集合视图不会滚动到最后一项。

但是,此调用破坏了我的集合视图单元格的布局。例如,如果我不调用scrollToItemAtIndexPath:,则集合视图(下方的白色区域)看起来像左边的——布局正确但显示了第一个项目。如果我调用scrollToItemAtIndexPath:,集合视图最初会显示最后一项,但布局会像右侧一样混乱(甚至不再显示日期)。

我做错了什么?

更多信息:

我在 ios 7 和 iOS 8 中都看到了这个错误。 我在 Xcode 6.1 中使用尺寸等级。

viewDidLayoutSubviews 的代码:

- (void)viewDidLayoutSubviews

    [super viewDidLayoutSubviews];

    NSIndexPath *lastIndexPath = [NSIndexPath indexPathForItem:self.unit.readings.count - 1 inSection:0];
    [self.readingCollectionView scrollToItemAtIndexPath:lastIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];

【问题讨论】:

【参考方案1】:

每当我遇到这个问题并且我有一个恒定大小的单元格时,我都会通过手动设置 contentOffset 并忽略 collectionView 方法来解决它。

self.collectionView.contentOffset = (CGPoint)
  .x = self.collectionView.contentSize.width - cell.width,
  .y = 0,
;

【讨论】:

这种方法有效。我只需要把这个调用放在viewWillLayoutSubviewsviewDidLayoutSubviews 中,因为contentSize.widthviewWillAppearviewDidLoad 中仍然为零。【参考方案2】:

我将以下内容放入viewWillLayoutSubviews(也适用于viewDidLayoutSubviews):

[self.readingCollectionView scrollToItemAtIndexPath:lastIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
[self.readingCollectionView reloadData];

一个 UI 问题仍然存在,但是:当视图控制器出现时,它显示第一个项目,然后立即刷新以显示最后一个项目。

为了解决这个看似无法解决的问题,我改用了 UI:在视图控制器出现之前显示“正在加载”标签,并在 viewDidAppear 中显示集合视图。

【讨论】:

以上是关于scrollToItemAtIndexPath 破坏 UICollectionViewCell 布局的主要内容,如果未能解决你的问题,请参考以下文章

scrollToItemAtIndexPath 破坏 UICollectionViewCell 布局

UICollectionView - 分离 scrollViewDidScroll 和 scrollToItemAtIndexPath

scrollToItemAtIndexPath 无法正常工作

UICollectionView scrollToItemAtIndexPath

如何知道 UICollectionView 是不是会在 scrollToItemAtIndexPath: 被调用后实际滚动?

在 scrollToItemAtIndexPath 之后获取 UICollectionView 单元格位置