CollectionKit 2.4.0

CollectionKit 2.4.0

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布上次发布2019年4月
SPM支持SPM

Luke Zhao维护。



  • Luke

CollectionKit

重新构想UICollectionView

一个用于构建可组合数据驱动的集合视图的现代Swift框架。

Carthage compatible Version License Build Status codecov Xcode 8.2+ iOS 8.0+ Swift 3.0+ Slack

迁移指南

v2.0

功能

  • UIScrollView之上重写UICollectionView
  • 自动区别数据变化并更新UI。
  • 通过cell重用、批量重载、仅视口diff以及 Swift值类型的使用,实现超凡性能。
  • 专为集合构建的内置布局和动画系统。
  • 具有独立布局的可组合部分。
  • 由Swift泛型驱动的严格类型检查。

安装

# CocoaPods
pod "CollectionKit"

# Carthage
github "SoySauceLab/CollectionKit"

入门指南

要开始使用CollectionKit,请用CollectionView替换UICollectionViewCollectionView是CollectionKit对UICollectionView的替代。你给它一个Provider对象,这个对象告诉CollectionView如何显示集合。

构建Provider最简单的方法是使用BasicProvider类。

BasicProvider

要构建一个BasicProvider,你需要以下内容

  • 数据源
    • 一个为BasicProvider提供数据的对象。
  • 视图源
    • 一个对象,将每个数据映射到视图,并根据需要进行视图更新。
  • 尺寸源
    • 一个函数,为每个单元格提供大小。

听起来很复杂,但事实上并不复杂。以下是一个简短的示例,演示了它是如何工作的。

let dataSource = ArrayDataSource(data: [1, 2, 3, 4])
let viewSource = ClosureViewSource(viewUpdater: { (view: UILabel, data: Int, index: Int) in
  view.backgroundColor = .red
  view.text = "\(data)"
})
let sizeSource = { (index: Int, data: Int, collectionSize: CGSize) -> CGSize in
  return CGSize(width: 50, height: 50)
}
let provider = BasicProvider(
  dataSource: dataSource,
  viewSource: viewSource,
  sizeSource: sizeSource
)

//lastly assign this provider to the collectionView to display the content
collectionView.provider = provider

请注意,我们在这里使用了ArrayDataSourceClosureViewSource。这两个类是CollectionKit内建的,应该能够满足大多数任务。你也可以实现自己的dataSourceviewSource。想象一下在你的项目中实现一个NetworkDataSource,它可以从json数据中检索并解析swift对象。

刷新

使用新数据更新CollectionView很容易。

dataSource.data = [7, 8, 9]

这将触发由此dataSource所服务的CollectionView进行更新。

请注意,append和其他数组的mutating方法也可用。

dataSource.data.append(10)
dataSource.data.append(11)
dataSource.data.append(12)

在这个例子中,我们更新了数组三次。每次更新都会触发一个刷新。你可能认为这非常计算密集,但事实并非如此。CollectionKit足够智能,只会在每个布局周期更新一次。它将等到下一次布局周期才真正刷新。

执行了上述3行代码后,CollectionView仍会显示[7, 8, 9]。但一旦完成当前运行循环周期,CollectionView会立即更新。你的用户不会注意到这个过程有任何滞后。

要立即触发更新,你可以调用collectionView.reloadDataprovider.reloadDatadataSource reloadData

要使CollectionView在下一个布局周期刷新,你可以调用collectionView.setNeedsReloadprovider.setNeedsReloaddataSource.setNeedsReload。你可能已经注意到,一旦你更新了ArrayDataSource内部的数组,基本上就是在为你调用setNeedsReload

请注意,如果你将数组分配给dataSource,然后更新这个数组,实际上并不会更新CollectionView。

var a = [1, 2 ,3]
dataSource.data = a
a.append(5) // won't trigger an update be cause dataSource.data & a is now two different array.
a = [4 ,5 ,6] // also won't trigger an update

布局

到如今,这个列表看起来仍然有些丑陋。每个单元格都靠左对齐,且之间没有任何间距。你可能会想要视图均匀分布,或者你可能会想要在项目或行之间添加一些间距。

这些都可以通过布局对象来实现。这里有一个例子。

provider.layout = FlowLayout(spacing: 10, justifyContent: .center)

FlowLayout 是 CollectionKit 内置的一个 Layout 类。还有许多其他内置布局,包括 WaterfallLayoutRowLayout。你也可以轻松地创建自己的布局。

FlowLayout 实际上是一个更高级的 UICollectionViewFlowLayout,它以行行的形式排列项目。它支持 lineSpacinginteritemSpacingalignContentalignItemsjustifyContent

每个布局也支持 inset(by:)transposed() 方法。

inset(by:) 为布局添加外部填充,并将结果布局作为 InsetLayout 返回。

let inset = UIEdgeInset(top: 10, left: 10, bottom: 10, right: 10)
provider.layout = FlowLayout(spacing: 10).inset(by: inset)

transposed() 将垂直布局转换为水平布局,或反之亦然。它返回原始布局被包装在 TransposedLayout 中。

provider.layout = FlowLayout(spacing: 10).transposed()

你还可以同时使用它们,如下所示

let inset = UIEdgeInset(top: 10, left: 10, bottom: 10, right: 10)
provider.layout = FlowLayout(spacing: 10).transposed().inset(by: inset)

关于布局有很多可以说的。我们将来会创建更多教程,教你如何创建自己的布局,并展示一些高级用法。与此同时,欢迎深入了解源代码。我向你保证它一点也不复杂。

组合(ComposedProvider)

CollectionKit 最好的特性之一,就是你可以将提供者自由组合在一起,在一个 CollectionView 中创建多个部分,而且这样做 确实非常简单

let finalProvider = ComposedProvider(sections: [provider1, provider2, provider3])

collectionView.provider = finalProvider

要更新单独的部分,只需更新其自己的 dataSource

provider2DataSource.data = [2]

你还可以实时更新周围的部分。

finalProvider.sections = [provider2, provider3, provider1]

或者添加更多。

finalProvider.sections.append(provider4)

你甚至可以将 ComposedProvider 放入另一个 ComposedProvider 中,不会有问题。

let trulyFinalProvider = ComposedProvider(sections: [finalProvider, provider5])

collectionView.provider = trulyFinalProvider

这有多酷!

动画

CollectionKit 提供了一个动画系统,允许您创建复杂的动画,并调整单元格的显示方式。

以下是在示例项目中包含的一些自定义动画器示例。它们可以与任何布局结合使用。这里我们使用了转置的瀑布流布局。

摇摆 边缘收缩 缩放

动画器还可以在单元格添加/移动/删除时执行动画。以下是一个显示3D缩放动画及其级联效果的示例。

使用 Animator 很简单。您可以将它分配给提供者、单元格或整个 CollectionView

// apply to the entire CollectionView
collectionView.animator = ScaleAnimator()

// apply to a single section, will override CollectionView's animator
provider.animator = FadeAnimator()

// apply to a single view, will take priority over all other animators
view.collectionAnimator = WobbleAnimator()

注意:要使用 WobbleAnimator,您必须在 podfile 中包含 pod "CollectionKit/WobbleAnimator" 子规范。

请查看示例项目以查看这些示例如何实际运行。

有问题?想贡献?

加入我们的公共 Slack