-
Notifications
You must be signed in to change notification settings - Fork 68
Expand file tree
/
Copy pathCocoaCollectionViewDiffableDataSource.swift
More file actions
125 lines (110 loc) · 4.97 KB
/
CocoaCollectionViewDiffableDataSource.swift
File metadata and controls
125 lines (110 loc) · 4.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#if os(macOS)
import AppKit
import DifferenceKit
/// A class for backporting `NSCollectionViewDiffableDataSource` introduced in macOS 10.15+.
/// Represents the data model object for `NSCollectionView` that can be applies the
/// changes with automatic diffing.
open class CocoaCollectionViewDiffableDataSource<SectionIdentifierType: Hashable, ItemIdentifierType: Hashable>: NSObject, NSCollectionViewDataSource {
/// The type of closure providing the item.
public typealias ItemProvider = (NSCollectionView, IndexPath, ItemIdentifierType) -> NSCollectionViewItem?
private weak var collectionView: NSCollectionView?
private let itemProvider: ItemProvider
private let core = DiffableDataSourceCore<SectionIdentifierType, ItemIdentifierType>()
/// Creates a new data source.
///
/// - Parameters:
/// - collectionView: A collection view instance to be managed.
/// - itemProvider: A closure to make the item.
public init(collectionView: NSCollectionView, itemProvider: @escaping ItemProvider) {
self.collectionView = collectionView
self.itemProvider = itemProvider
super.init()
collectionView.dataSource = self
}
/// Applies given snapshot to perform automatic diffing update.
///
/// - Parameters:
/// - snapshot: A snapshot object to be applied to data model.
/// - animatingDifferences: A Boolean value indicating whether to update with
/// diffing animation.
/// - completion: An optional completion block which is called when the complete
/// performing updates.
public func apply(_ snapshot: DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>, animatingDifferences: Bool = true, completion: (() -> Void)? = nil) {
core.apply(
snapshot,
view: collectionView,
animatingDifferences: animatingDifferences,
performUpdates: { collectionView, changeset, setSections in
collectionView.reload(using: changeset, setData: setSections)
},
completion: completion
)
}
/// Returns a new snapshot object of current state.
///
/// - Returns: A new snapshot object of current state.
public func snapshot() -> DiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType> {
return core.snapshot()
}
/// Returns an section identifier for given section index.
///
/// - Parameters:
/// - section: An section index for the section identifier.
///
/// - Returns: An section identifier for given section index.
public func sectionIdentifier(for section: Int) -> SectionIdentifierType? {
return core.sectionIdentifier(for: section)
}
/// Returns an item identifier for given index path.
///
/// - Parameters:
/// - indexPath: An index path for the item identifier.
///
/// - Returns: An item identifier for given index path.
public func itemIdentifier(for indexPath: IndexPath) -> ItemIdentifierType? {
return core.itemIdentifier(for: indexPath)
}
/// Returns an index path for given item identifier.
///
/// - Parameters:
/// - itemIdentifier: An identifier of item.
///
/// - Returns: An index path for given item identifier.
public func indexPath(for itemIdentifier: ItemIdentifierType) -> IndexPath? {
return core.indexPath(for: itemIdentifier)
}
/// Returns the number of sections in the data source.
///
/// - Parameters:
/// - collectionView: A collection view instance managed by `self`.
///
/// - Returns: The number of sections in the data source.
public func numberOfSections(in collectionView: NSCollectionView) -> Int {
return core.numberOfSections()
}
/// Returns the number of items in the specified section.
///
/// - Parameters:
/// - collectionView: A collection view instance managed by `self`.
/// - section: An index of section.
///
/// - Returns: The number of items in the specified section.
public func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
return core.numberOfItems(inSection: section)
}
/// Returns an item at specified index path.
///
/// - Parameters:
/// - collectionView: A collection view instance managed by `self`.
/// - indexPath: An index path for item.
///
/// - Returns: An item at specified index path.
open func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
let itemIdentifier = core.unsafeItemIdentifier(for: indexPath)
guard let item = itemProvider(collectionView, indexPath, itemIdentifier) else {
universalError("NSCollectionView dataSource returned a nil item at index path: \(indexPath), collectionView: \(collectionView), itemIdentifier: \(itemIdentifier)")
}
return item
}
}
#endif