CollectionView循环滚动机制点睛

作者: L泽 | 来源:发表于2016-11-10 18:11 被阅读1119次

    突然想起很早前有个大神问我的一个关于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可以给我私信。有什么不能解决的需求问题也可以给我看看,让我也接触一些高深莫测的东西。顺手点个喜欢不是很好么?嘿嘿嘿。

    相关文章

      网友评论

        本文标题:CollectionView循环滚动机制点睛

        本文链接:https://www.haomeiwen.com/subject/wiatpttx.html