突然想起很早前有个大神问我的一个关于collectionView循环的问题,当时我没有去接触过这个内容,所以就随便说了下(敷衍了事)。现在突然发现这是个值得记录一下的内容,于是乎,我就在这里分享一下我的思路。(当然也有其他的思路啦。最重要是你需要会一种)。
1.先说一下collectionView的一个必要类。
_collectionView =[[UICollectionView alloc]initWithFrame:CGRectMake(0, 0, CGRectGetWidth(frame), CGRectGetHeight(frame)) collectionViewLayout:yourLayout];
其中这个yourLayout就是你自己定制的布局属性类。在这个属性里面,你可以做出世界上不曾出现的动画效果。唯一要求的就是你有多少创造力;
首先你创造自己自定义的布局属性继承于UICollectionViewFlowLayout
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{}
在上述方法中将位于最中间的index值通过自己的方法传输到collectionView所在的view中。(这个值是实时传输的。我自己用的是block传值的方式。毕竟好写啊O(∩_∩)O哈哈哈~)
(1)注意重点了,如果你的工程中一个collectionView的item尺寸宽度刚好是一个屏幕的宽度,或者你在如下代码中
NSArray *array = [self.collectionView indexPathsForVisibleItems];
能够明确得出此数组中哪个是你的目标item。那么你可以用如下代码确定最中间的index值。
NSIndexPath *indexPath = array[0];
NSInteger row = indexPath.row;
这样就不需要用传值的方式来得到目标item的下标了。
2.接下来就是最关键的思路了
对于cellectionView中数据源的处理应该就是精髓了,(其实也没有什么。。。。)我把它称为真假数据源。真数据就是平常普通的装model的数据源啦。那么假的呢?\(o)/~先进一段广告
都知道数据源是一个有头有尾的数组。collectionView的滚动过程中肯定可以把数据滚动显示到最后一个。然后呢,就是不可滚动了。这样就不能实现无线滚动的效果了。如果你觉得滚到最后做一个无动画跳转到第一个就可以了,那确实可以类似无限滚动,但是就不能体现流畅的效果,而且会让用户觉得很突兀。
因此我创建了假的数据源,这个数据源装的是下标,比如真实数据源有5个元素。我创建的数据源就是 @[@0, @1, @2, @3, @4, @0, @1, @2, @3, @4,@0, @1, @2, @3, @4,@0, @1, @2, @3, @4,@0, @1, @2, @3, @4,......循环177次,哈哈,7是一个很谦恭的数字,自己随便哈。别影响性能就好。如何创建就不说了,for循环。
//创建全局变量currentSelectedIndex,也是实时传输的index值;
//创建好了数据源就刷新数据
[self.collectionView reloadData];
// self.dataSource 是假数据源 , 5和177固定值最好宏定义 。centerItem是假数据源中最中间的一组数据。
NSInteger centerItem = 5 *(177 - 1)/2;
NSIndexPath *index = [NSIndexPath indexPathForItem:centerItem inSection:0];
[self.collectionView scrollToItemAtIndexPath:index atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
然后就是在cellectionView代理方法中的操作了
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return self.dataSource.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
YourCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"YourCell" forIndexPath:indexPath];
NSNumber *index = self.dataSourcese[indexPath.item];
NSInteger *indexValue = [num integerValue] % 5;
//真实数据源中装的都是图片地址
cell.image = self.imagesArray[indexValue];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
[collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
}
最后很重要的就是当用户滑动之后,处于减速的时候调用scrollView的代理方法。
无缝回滚到中间
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
NSIndexPath *index = [NSIndexPath indexPathForItem:self.currentSelectedIndex Section:0];
[self.collectionView scrollToItemAtIndexPath: index atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
}
至此已经完成了整个循环滚动精华部分的述说。
如果希望看demo可以给我私信。有什么不能解决的需求问题也可以给我看看,让我也接触一些高深莫测的东西。顺手点个喜欢不是很好么?嘿嘿嘿。