UICollectionView套UICollectionView,无限滑动预加载

795 阅读2分钟

最近做的一个需求,看起来简单,实则很多坑。 需求:上下滑动的UICollectionView中套一个左右滑动的UICollectionView,要求无感无限滑动刷新,内容宽度要自适应,重新显示的时候内容位置不能改变,当内部UICollectionView没有数据时,不显示该UICollectionView。

需求分析: 1、父UICollectionView中增加一种cell,cell内部套子UICollectionView 2、子UICollectionView的cell宽度自适应 3、无限滑动,意味着数据量很大,还得预加载 4、cell重用时位置不变 5、无数据时不显示该cell

实现: 1、没啥难度

2、cell宽度自适应,两种方法 一、设置estimatedItemSize,在cell中重写preferredLayoutAttributesFitting方法,让ui自动调整 性能不好,数据量大的时候会卡顿,产生各种奇怪的bug。

二、在cellViewModel中计算宽度,在UICollectionViewDelegateFlowLayout协议中返回,推荐使用

3、预加载,首先想到的是mjrefresh,不过可惜没有横向刷新。于是自己找了一些别的横拉刷新的库,要么有bug,要么不好用,而且都没有自动刷新的功能。

预刷新实现:同样有两种思路 一、监听contentoffset,与contentsize.frame.width差值达到设定值时,请求下一页数据,这种方式在cell宽度不一致时会有偏差 二、在cell重用时,根据index与数组的差值,达到设定值时,请求下一页,这种预加载方式推荐使用,此处需要注意重复加载的情况

4、cell重用时位置不变,那就需要我们记录离开时的contentoffset,在出现时赋值 ,也有两种思路 一:监听collectionview的滑动停止时的contentoffset,在cell重用时赋值。scrollview根据有无加速度,停止的时候有2个方法接受事件,所以该方法很不优雅,并且我测试时会有偏差。 二、在didEndDisplayingCell时记录contentoffset,在willDisplayCell时赋值

5、根据有无数据决定是否显示该cell,该需求的难点在于:子UICollectionView在网络请求结束后才能知道有无数据,在此之前父UICollectionView已经决定了布局了。所以应该在子vm数据请求后,想办法去改变父vm的数据,并reload一次。此处需要注意首次添加子vm数据时也需要判断是否有无数据。