我正在为UICollectionView制作一个水平布局,以表示时间线。理想情况下,我希望它能无限滚动,但我不确定什么是正确的方法
现在,我从UICollectionViewLayout的一个子类和一个只有3个单元格的简单例子开始。我覆盖scrollView委托方法scrollViewDidEndDecelerating
,跳回中心卡并偏移我的模型以匹配。
这是有效的,除非用户快速滚动,并且他们到达另一张卡的末尾。他们被"抓住"了,必须释放集合视图。当视图停止减速时,居中发生,它们能够继续。
我在GitHub上有一个演示。
我想知道是否还有其他方法,或者我缺少的东西。我熟悉苹果公司关于无限滚动视图的WWDC演示,也看过滚动文本的演示项目,但我不知道如何使用页面或集合视图。
有人能帮忙吗?
如果您想知道用户何时移动到新页面,则应该使用scrollViewDidScroll
。正如您所发现的,如果用户快速滚动,则不会调用scrollViewDidEndDecelerating
,因为滚动视图从未停止移动。
我已将您的代码调整为:
- 在
scrollViewDidScroll
而不是scrollViewDidEndDecelerating
上触发 - 使用集合视图边界的中心点来测试索引路径(然后,当第一个或第三个单元格位于屏幕的一半时,这会导致单元格更新)
- 直接设置内容偏移量,而不是滚动到索引路径,从滚动视图的当前位置跳一整页
这是代码:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[self centerIfNecessary];
}
- (void)centerIfNecessary
{
// Fetch the index path in the middle of the collection view
NSIndexPath *visibleIndexPath = [self.collectionView indexPathForItemAtPoint:CGPointMake(self.collectionView.contentOffset.x +
self.collectionView.bounds.size.width/2,
self.collectionView.contentOffset.y)];
NSInteger row = visibleIndexPath.row;
// Three cases: Row is 0, so we've moved left.
// Row is 1, we haven't moved.
// Row is 2, we've moved right.
if (row == 0)
{
self.date = [[self calendar] dateBySubtractingDays:1 fromDate:self.date];
self.collectionView.contentOffset = CGPointMake(self.collectionView.contentOffset.x +
self.collectionView.bounds.size.width,
self.collectionView.contentOffset.y);
[self.collectionView reloadData];
}
else if (row == 2)
{
self.date = [[self calendar] dateByAddingDays:1 toDate:self.date];
self.collectionView.contentOffset = CGPointMake(self.collectionView.contentOffset.x -
self.collectionView.bounds.size.width,
self.collectionView.contentOffset.y);
[self.collectionView reloadData];
}
}
您可以在水平UICollectionView的两侧添加额外的单元格,使其看起来像一个无限滚动滚动视图。如果contentOffset位于左侧附近,则在滚动内容视图的右侧显示完全相同的单元格。我想你可以从gitHub中的HFSwipeView控件中了解如何实现这个问题。