Skip to content

Commit 0663b17

Browse files
committed
README update
1 parent 4a61ce8 commit 0663b17

File tree

1 file changed

+155
-0
lines changed

1 file changed

+155
-0
lines changed

README.md

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,161 @@
88

99
UITableViewController and UICollectionViewController based on a DiffableDataSource.
1010

11+
## Requirements
12+
- macOS 10.15+ (Catalyst)
13+
- iOS 13.0+
14+
- tvOS 13.0+
15+
- watchOS 6.0+
16+
17+
## Installation
18+
19+
### [Swift Package Manager](https://swift.org/package-manager/)
20+
21+
Add the following to the dependencies of your `Package.swift:
22+
23+
```swift
24+
.package(url: "https://github.com/FelixHerrmann/FHDiffableViewControllers", from: "x.x.x")
25+
```
26+
27+
### Manual
28+
29+
Download the files in the [Sources](https://github.com/FelixHerrmann/FHDiffableViewControllers/tree/master/Sources) folder and drag them into you project.
30+
31+
## Usage
32+
33+
If you are using Swift Package Manager, you have to import FHDiffableViewControllers to your file with `import FHDiffableViewControllers`. You can also import it globally with `@_exported import FHDiffableViewControllers`. (e.g. in `AppDelegate.swift`)
34+
35+
Now you can inherit your view controller class from `FHDiffableTableViewController` and `FHDiffableCollectionViewController`.
36+
37+
But first we need a `SectionIdentifier` and `ItemIdentifier` which will be used for the generic types. Both types have to conform to `Hashable`.
38+
39+
```swift
40+
enum Section {
41+
case main, detail
42+
}
43+
44+
struct Item: Hashable {
45+
var title: String
46+
}
47+
```
48+
>It is recommend to conform the item to `Identifiable` because the app crashes if there are duplicates in the data source!
49+
50+
These types can be used like that:
51+
52+
```swift
53+
class ViewController: FHDiffableTableViewController<Section, Item> {
54+
override viewDidLoad() {
55+
super.viewDidLoad()
56+
57+
applySnapshot([
58+
FHDiffableDataSourceSnapshotSection(
59+
sectionIdentifier: .main,
60+
itemIdentifiers: [
61+
Item(title: "First Item"),
62+
Item(title: "Second Item")
63+
]
64+
),
65+
FHDiffableDataSourceSnapshotSection(
66+
sectionIdentifier: .detail,
67+
itemIdentifiers: [
68+
Item(title: "Third Item")
69+
]
70+
)
71+
], animatingDifferences: false)
72+
}
73+
}
74+
```
75+
>This is the most simple implementation of a FHDiffableTableViewController.
76+
77+
### Customize Cells
78+
79+
In order to use custom cells, the `cellProvider` property must be overritten. This works exactly the same for table view and collection view.
80+
81+
```swift
82+
override var cellProvider: UITableViewDiffableDataSource<Section, Item>.CellProvider {
83+
return { (tableView, indexPath, item) in
84+
let cell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as? CustomCell
85+
cell?.textLabel?.text = item.title
86+
return cell
87+
}
88+
}
89+
```
90+
91+
Do not forget to register the cell bevor you call `applySnapshot(_:)` the first time!
92+
93+
```swift
94+
tableView.register(CustomCell.self, forCellReuseIdentifier: "customCell")
95+
```
96+
97+
### Customize Header and Footer Views (only collection view)
98+
99+
In order to use custom header or footer views, the `supplementaryViewProvider` property must be overritten.
100+
101+
```swift
102+
override var supplementaryViewProvider: UICollectionViewDiffableDataSource<Section, Item>.SupplementaryViewProvider {
103+
return { (collectionView, kind, indexPath) in
104+
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "customHeader", for: indexPath) as? CustomHeader
105+
switch self.dataSource.snapshot().sectionIdentifiers[indexPath.section] {
106+
case .main:
107+
headerView?.backgroundColor = .systemGreen
108+
case .detail:
109+
headerView?.backgroundColor = .systemPink
110+
}
111+
return headerView
112+
}
113+
}
114+
```
115+
116+
Do not forget to register the cell bevor you call `applySnapshot(_:)` the first time!
117+
118+
```swift
119+
collectionView.register(CustomHeader.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "customHeader")
120+
```
121+
122+
### Custom Data Source
123+
124+
In case you want to change the behavior of the title creation or you want to use section index titles and other features you have to subclass the appropriate data source. For the table view it could look something like that:
125+
126+
```swift
127+
class CustomDataSource: UITableViewDiffableDataSource<Section, Item> {
128+
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
129+
switch snapshot().sectionIdentifiers[section] {
130+
case .main:
131+
return "Main"
132+
case .detail:
133+
return "Detail"
134+
}
135+
}
136+
}
137+
```
138+
139+
>Use `UICollectionViewDiffableDataSource` for collection view.
140+
141+
So that it can be used in our view controller we have to create a lazy var of this and override the `dataSource` property with it.
142+
143+
```swift
144+
lazy var customDataSource = CustomDataSource(tableView: tableView, cellProvider: cellProvider)
145+
146+
override var dataSource: UITableViewDiffableDataSource<Section, Item> {
147+
return customDataSource
148+
}
149+
```
150+
151+
### Custom `applySnapshot(_:)`
152+
153+
You are not forced to use `applySnapshot(_:)` in combination with `FHDiffableDataSourceSection` array to apply snapshots to your `dataSource`. You can override the `applySnapshot(_:)` to change its behavior, create your own `applySnapshot()` method or do it manually as follows:
154+
155+
```swift
156+
var snapshot = FHSnapshot()
157+
snapshot.appendSections([.main, .detail])
158+
snapshot.appendItems([Item(title: "Main Item")], toSection: .main)
159+
snapshot.appendItems([Item(title: "Detail Item")], toSection: .detail)
160+
dataSource.apply(snapshot, animatingDifferences: true, completion: nil)
161+
```
162+
163+
### init(layout:)
164+
165+
I use a custom initializer for the `FHDiffableCollectionViewController` which is based on an enum. This contains a case for `UICollectionViewFlowLayout`, for `UICollectionViewCompositionalLayout`, for a custom `UICollectionViewLayout` or a default case. The default case creates a compositional layout which is only intended to be used for testing.
11166

12167
## License
13168

0 commit comments

Comments
 (0)