-
-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathViewRegistration.swift
178 lines (156 loc) · 5.77 KB
/
ViewRegistration.swift
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
//
// Created by Jesse Squires
// https://www.jessesquires.com
//
// Documentation
// https://jessesquires.github.io/ReactiveCollectionsKit
//
// GitHub
// https://github.com/jessesquires/ReactiveCollectionsKit
//
// Copyright © 2019-present Jesse Squires
//
import Foundation
import UIKit
/// Describes all information needed to register a view for reuse with a `UICollectionView`.
public struct ViewRegistration: Hashable, Sendable {
/// The view reuse identifier.
public let reuseIdentifier: String
/// The type of view to register.
public let viewType: ViewRegistrationViewType
/// The view registration method.
public let method: ViewRegistrationMethod
/// Initializes a `ViewRegistration`.
///
/// - Parameters:
/// - reuseIdentifier: The view reuse identifier.
/// - viewType: The type of view to register.
/// - method: The view registration method.
public init(
reuseIdentifier: String,
viewType: ViewRegistrationViewType,
method: ViewRegistrationMethod
) {
self.reuseIdentifier = reuseIdentifier
self.viewType = viewType
self.method = method
}
// MARK: Dequeuing Views
@MainActor
func dequeueViewFor(collectionView: UICollectionView, at indexPath: IndexPath) -> UICollectionReusableView {
switch self.viewType {
case .cell:
return self._dequeueCellFor(collectionView: collectionView, at: indexPath)
case .supplementary(let kind):
return self._dequeueSupplementaryViewFor(kind: kind, collectionView: collectionView, at: indexPath)
}
}
@MainActor
private func _dequeueCellFor(collectionView: UICollectionView, at indexPath: IndexPath) -> UICollectionViewCell {
collectionView.dequeueReusableCell(withReuseIdentifier: self.reuseIdentifier, for: indexPath)
}
@MainActor
private func _dequeueSupplementaryViewFor(kind: String, collectionView: UICollectionView, at indexPath: IndexPath) -> UICollectionReusableView {
collectionView.dequeueReusableSupplementaryView(
ofKind: kind,
withReuseIdentifier: self.reuseIdentifier,
for: indexPath
)
}
// MARK: Registering Views
@MainActor
func registerWith(collectionView: UICollectionView) {
switch self.viewType {
case .cell:
self._registerCellWith(collectionView: collectionView)
case .supplementary(let kind):
self._registerSupplementaryView(kind: kind, with: collectionView)
}
}
@MainActor
private func _registerCellWith(collectionView: UICollectionView) {
switch self.method {
case .viewClass(let anyClass):
collectionView.register(anyClass, forCellWithReuseIdentifier: self.reuseIdentifier)
case .nib(let name, let bundle):
let nib = UINib(nibName: name, bundle: bundle)
collectionView.register(nib, forCellWithReuseIdentifier: self.reuseIdentifier)
}
}
@MainActor
private func _registerSupplementaryView(kind: String, with collectionView: UICollectionView) {
switch self.method {
case .viewClass(let anyClass):
collectionView.register(
anyClass,
forSupplementaryViewOfKind: kind,
withReuseIdentifier: self.reuseIdentifier
)
case .nib(let name, let bundle):
let nib = UINib(nibName: name, bundle: bundle)
collectionView.register(
nib,
forSupplementaryViewOfKind: kind,
withReuseIdentifier: self.reuseIdentifier
)
}
}
}
/// Initializes a `ViewRegistration`.
///
/// - Parameters:
/// - reuseIdentifier: The view reuse identifier.
/// - viewType: The type of view to register.
/// - method: The view registration method.
extension ViewRegistration {
/// Convenience initializer for a class-based cell.
///
/// - Parameters:
/// - reuseIdentifier: The cell reuse identifier.
/// - cellClass: The cell class.
public init(reuseIdentifier: String, cellClass: AnyClass) {
self.init(
reuseIdentifier: reuseIdentifier,
viewType: .cell,
method: .viewClass(cellClass)
)
}
/// Convenience initializer for a nib-based cell in the main bundle.
///
/// - Parameters:
/// - reuseIdentifier: The cell reuse identifier.
/// - cellNibName: The nib name for the cell.
public init(reuseIdentifier: String, cellNibName: String) {
self.init(
reuseIdentifier: reuseIdentifier,
viewType: .cell,
method: .nib(name: cellNibName, bundle: nil)
)
}
/// Convenience initializer for a class-based supplementary view.
///
/// - Parameters:
/// - reuseIdentifier: The view reuse identifier.
/// - supplementaryViewClass: The view class.
/// - kind: The supplementary view kind.
public init(reuseIdentifier: String, supplementaryViewClass: AnyClass, kind: String) {
self.init(
reuseIdentifier: reuseIdentifier,
viewType: .supplementary(kind: kind),
method: .viewClass(supplementaryViewClass)
)
}
/// Convenience initializer for a nib-based supplementary view in the main bundle.
///
/// - Parameters:
/// - reuseIdentifier: The view reuse identifier.
/// - supplementaryViewNibName: The nib name for the view.
/// - kind: The supplementary view kind.
public init(reuseIdentifier: String, supplementaryViewNibName: String, kind: String) {
self.init(
reuseIdentifier: reuseIdentifier,
viewType: .supplementary(kind: kind),
method: .nib(name: supplementaryViewNibName, bundle: nil)
)
}
}