最近一直在做项目优化,由于项目中有一个 xx墙
的列表界面,Cell的样式复杂,与用户的互动,cell变化也比较多,所以在实现上,代码很臃肿,比较杂乱,日常的维护不是特别方便,随着时间的推移,这个问题肯定越来越麻烦,所以一直在找神马方法来有效的处理这个问题。
之后就找到了IGListKit这个库,其实这个库在很早之前就有所接触,当时只是简单的了解了一下,看了它能实现的东西,自己原生也能写出来,就没有去深入的学习它。现在再想想,是以前自己太幼稚了。
其实,IGListKit这个库的目的性很强,它就是来解决一个布局复杂多样,交互比较多的列表
的编写和维护难的问题,官方对其的描述是:A data-driven UICollectionView framework for building fast and flexible lists.
,这也刚好,符合我的需求。
Diff
Diff 指的是在新旧的数据中,找出不同。IGListKit中,我觉得最后特色的地方,是它的 Diff 方案,IGListKit的 Diff 结合了Paul Heckel’s Diff(1978年)的一篇论文,进一步优化,使用额外一些内存空间,降低时间复杂度到O(n),并且能准确获取所有Insert/Delete/Move操作。因此,IGListKit在更新列表内容时,并不是对所有的cell进行reloadData()
,而是使用Diff算法,计算出新旧数据的差异,然后使用performUpdates进行小范围的insert/delete/move操作对数据发生变化的视图进行更新。
如何使用
- 创建
collectionView
和adapter
, 在viewDidLayoutSubviews
中设置collectionView.frame = view.bounds
,设置adapter
的viewController
为self
,adapter
的collectionView
为刚刚创建的collectionView
,最后设置adapter
的dataSource
为self
;
2.实现 ListAdapterDataSource
的方法
numberOfItems()
、sizeForItem(at index: Int) -> CGSize
、cellForItem(at index: Int) -> UICollectionViewCell
、didUpdate(to object: Any)
4个方法,另外还可以重写 ListSectionController 的其他方法来实现不同的需求,比如inset、space的设置、selected、highlight方法、以及supplementaryViewSource、displayDelegate、workingRangeDelegate、scrollDelegate这几种很好用的delegate。
部分说明
下图,挺形象的描述了 IGListKit 的实现(网络图片,借用一下)
- 其中
adapter
的角色是一个中心调度器,它作为UICollectionView的datasource
,每次都会从sectionController
中获取cell
,同时作为UICollectionView
和UIScrollView的delegate
,负责向sectionController
回调。同时,adapter
对外提供datasource
回调,外界需要提供data
数组、sectionController
的对象实例、以及empty view
。 SectionController
中的collectionContext
实际就是就是adapter
,上两者是相互引用的关系。- 上述的Demo也可以用
IGListKit
内建的ListBindingSectionController
来实现,具体看实现开发来选择用哪种。 IGListKit
内建的SectionController
还有IGListSingleSectionController
,可以构建简单的单个cell
的Section
。IGListKit
内建的SectionController
中的IGListGenericSectionController
,是在IGListSectionController
的基础上,自动添加了一个属性来存储 ``didUpdateToObject:方法中的
Object`IGListKit
内建的SectionController
中的ListStackedSectionController
,是将多个SectionController
组合在一个SectionController
中处理。