Conv
Conv smart represent UICollectionView data structure more than UIKit.
Easy definition for UICollectionView DataSource and Delegate methods.
And Conv reload fast to use diffing algorithm based on the Paul Heckel's algorithm.
Insert and Delete | Move item and section |
---|---|
Conv(called KONBU) means Seaweed in Japan.
This library is inspired by Shoyu. Thanks @yukiasai.
Usage
First, Conv need to prepare array of definition datastructure for section and item. And then it should conform Differenciable
protocol for difference algorithm.
Section
enum SectionType: Int {
case one
case two
case three
static var allCases: [SectionType] {
return [.one, .two, .three]
}
}
extension SectionType: Differenciable {
var differenceIdentifier: DifferenceIdentifier {
return "\(self)"
}
}
let sectionTypes = SectionType.allCases
Item
struct ItemModel {
let index: Int
let imageName: String
var image: UIImage {
return UIImage(named: imageName)!
}
}
extension ItemModel: Differenciable {
var differenceIdentifier: DifferenceIdentifier {
return "\(index)" + imageName
}
}
let itemModels = [
ItemModel(index: 1, imageName: "forest"),
ItemModel(index: 2, imageName: "moon"),
ItemModel(index: 3, imageName: "pond"),
ItemModel(index: 4, imageName: "river"),
]
Second, start to define data structure for section and item.
It use prepared Differenciable array.
collectionView
.conv // #1
.diffing()
.start()
.append(for: sectionTypes) { (sectionType, section) in // #2
section.append(.header, headerOrFooter: { (header: SectionHeaderFooter<ListCollectionReusableView>) in // #3
header.reusableIdentifier = "ListCollectionReusableView"
header.size = CGSize(width: UIScreen.main.bounds.width, height: 50)
header.configureView { view, _ in
view.nameLabel.text = "\(sectionType)".uppercased()
view.nameLabel.textColor = .white
view.backgroundColor = sectionType.backgroundColor
}
})
section.append(for: itemModels, items: { (itemModel, item: Item<ListCollectionViewCell>) in // #4
item.reusableIdentifier = "ListCollectionViewCell"
item.sizeFor({ _ -> CGSize in
let gridCount: CGFloat = 3
let edge = floor((UIScreen.main.bounds.width - (gridCount - 1)) / gridCount)
let size = CGSize(width: edge, height: edge)
return size
})
item.configureCell { (cell, info) in
cell.setup(with: itemModel)
}
item.didSelect { [weak self] (item) in
let viewController = DetailViewController(imageName: itemModel.imageName)
self?.navigationController?.pushViewController(viewController, animated: true)
}
})
}
This swift code has the following meaning. It explain for #
mark in code.
- Start to define UICollectionView data structure it using
Conv
. - Append sections that number of sectionTypes. And start define about section.
- Append section header for each section. And start define about section header.
- Append items that number of itemModels for each section. And start define about item.
Last, If you want to render of collectionView
, you call collectionView.update()
your best timing.
update()
calculate diff for minimum reloading data between before section and between before items.
collectionView.conv.update()
Or if you want to all realod cells, you can call reload()
. It will be same behavior of collectionView.reloadData()
.
collectionView.conv.reload()
You can see more example to ConvExmaple
Algorithm
Conv to use diffing algorithm based on the Paul Heckel's algorithm.
And I also referred to other libraries below.
- https://github.com/mcudich/HeckelDiff
- https://github.com/ra1028/DifferenceKit
- https://github.com/Instagram/IGListKit/
Install
CocoaPods
Conv is available through Cocoapods.
You can write it into target and exec pod install
.
pod 'Conv'
Carthage
Conv is available through Carhtage.
You can write it into target and exec carthage update --platform iOS
. And find conv framework and embed your project.
github 'bannzai/Conv'
Why Conv?
UIKit.UICollectionView has some problems.
- UICollectionView.dequeueXXX method not type safe. So, should convert to want class each cells.
- UICollectionViewDataSource and UICollectionViewDelegate(or DelegateFlowLayout) far away each configured functions. So, reading configuration flow for each indexPath very difficalt.
- Many case to use UICollectionView with Array. But extract element from array using indexPath many time.
Conv resolve these problem.
- Conv does not need to call UICollectionView.dequeueXXX. Because you can define configureCell method and get converted custom class cell.
section.append(for: itemModels, items: { (itemModel, item: Item<ListCollectionViewCell>) in // #4
...
item.configureCell { (cell, info) in
// cell is converted ListCollectionViewCell
cell.setup(with: itemModel)
}
})
-
You can write to neary for each UICollectionView component. section,item,header and footer. So, this definition to be natural expression for UICollectionView data strcture, hierarchy, releation.
-
When append section or item, you can passed allCases for configure UICollectionView. Next each element pass closure argument that define Conv.Section or Conv.Item. So, You can represent CollectionView data structure with extracted each element.
LICENSE
Conv is released under the MIT license. See LICENSE for details.
Header logo is released CC BY-NC 4.0 license. Original design by noainoue.