带有无限滚动的UICollectionView?

6
我正在尝试使用无限滚动的方式来实现一个集合视图。滚动应该是循环的,就像在 UIPickerView 中一样。这能够使用苹果的 UICollectionView 实现吗?还是只能创建一个水平的 PickerView?
你觉得呢?

你的意思是无限循环显示一定数量的元素吗? - Eric
即使你能做到,也不应该这样做。UICollectionView并不是为那种行为设计的,即使你能解决问题,它的性能也会非常差。 - DBD
@Eric:是的,就像UIPickerView一样。 - Alex1987
3
@DBD,性能会变差这种说法不是真的。由于单元格的重复利用,即使有多少可见行,实际上的单元格数也永远不会超过一次性能看到的数量。 - rdelmar
示例代码在这里:https://dev59.com/dGUp5IYBdhLWcg3wEETd#15553973 - Hai Feng Kao
2
@DBD 错了,请看日历应用程序。 - aryaxt
4个回答

3
你应该观看WWDC 2011会议的“高级ScrollView技术”视频,他们讲解了无限滚动,并且我相信可以将其与UICollectionView一起使用。它在你滚动时重新居中,然后将新项目放置在当前可见项目之后(或之前,具体取决于滚动方向)。
正如他们在会议上所说的那样,你不应该使用一种有结尾的方法。正如会议中所述:人们肯定会在某个时候找到边缘。

-1
感谢rdelmar提供的巧妙解决方案。那个“collectionView:numberOfItemsInSection”中使用大数的想法非常有效。我尝试使用UIScrollView委托方法实现相同的效果,但输出却很卡顿。
以下是我的代码的一部分。
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {

return 100;}

// CellforRow

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

// Setup cell identifier
static NSString *cellIdentifier = @"cvCell";


CVCell *cell;
        cell = (CVCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];

        [cell.titleLabel setText:[self.dataArray objectAtIndex:(indexPath.row)%self.dataArray.count]];

return cell;

}

// DidSelect

-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{


NSLog(@"Index path is %d", indexPath.row%self.dataArray.count);

}

这将提供无限滚动效果。 要启用双向无限滚动,请在ViewWillAppear中使用ScrolltoIndexpath:(Itemscount的中间)! 希望这能帮助即将构建无限滚动UICollectionView的人。


-1
是的,你可以这样做。在collectionView:numberOfItemsInSection:方法中返回一个非常大的数字,在collectionView:cellForItemAtIndexPath:方法中使用模运算符,始终返回indexPath.Row的值在0到数据数组的最后一个索引之间。所以如果你的数组中有20个项目,你可以像这样做:
item.whatever.text = [self.theData objectAtIndex:indexPath.row %20];

1
@rdelmar 这是一个错误的假设!事实上,你必须欺骗用户,因为它从来不是真正的无限滚动。但是有更好的方法来实现它。如果需要,只需将项目添加到末尾/开头,这样就没有结束了。这似乎比你的解决方案更“无限”。 - Guido Hendriks
1
@rdelmar 实现WWDC会议上的内容并不难。如果你不知道如何正确地做某件事,那么你只是采用了错误的方法,而不是学习如何以正确的方式去做它?是的,我确实给你的回答点了个踩。当我这样做时,它的得分是+1,所以显然我不是唯一一个这样做的人... - Guido Hendriks
1
@GuidoH,你说得对,这并不难——我以前尝试过类似的东西,但是在scrollViewDidScroll中进行偏移调整会导致非常抖动的结果,因此我认为需要相当多的代码才能做到。实际上,用集合视图比视频中所做的要容易得多,因为集合视图已经处理了他们忽略的所有平铺工作。感谢你提醒我,今年我看了很多视频,但是错过了那个视频。 - rdelmar
@Ash,我可能有一个测试项目,但我现在不在家。明天我会找到它并在某个地方发布。 - rdelmar
@rdelmar。非常感谢,那太好了。我一直在尝试使用集合视图创建无限水平滚动。如果更容易的话,您可以通过电子邮件或此处向我发送测试项目的链接。 - Ash
显示剩余6条评论

-1
重写此方法以启用双向无限滚动。每当内容距离中心太远且用户从未到达末尾时,它会将内容居中。
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGPoint currentOffset = self.collectionView.contentOffset;
CGFloat contentWidth = self.collectionView.contentSize.width;
CGFloat centerOffsetX = (contentWidth - self.collectionView.bounds.size.width) / 2.0;
CGFloat distanceFromCenter = fabs(currentOffset.x - centerOffsetX);

if (distanceFromCenter > (contentWidth / 4.0)) {
    self.collectionView.contentOffset = CGPointMake(centerOffsetX, currentOffset.y);
}

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接