@@ -72,6 +72,8 @@ open class TableViewDriver: NSObject {
72
72
73
73
private let _automaticDiffingEnabled : Bool
74
74
75
+ private let _lightweightDiffing : Bool
76
+
75
77
/// Initializes a data source that drives a `UITableView` based on a `TableViewModel`.
76
78
///
77
79
/// - Parameters:
@@ -82,14 +84,19 @@ open class TableViewDriver: NSObject {
82
84
/// - automaticDiffingEnabled: defines whether or not this data source updates the table
83
85
/// view automatically when cells/sections are moved/inserted/deleted.
84
86
/// Defaults to `true`.
87
+ /// - lightweightDiffing: when enabled, simply diff the count of rows rather than generating full changesets.
88
+ /// Defaults to `false`.
85
89
public init (
86
90
tableView: UITableView ,
87
91
tableViewModel: TableViewModel ? = nil ,
88
92
shouldDeselectUponSelection: Bool = true ,
89
- automaticDiffingEnabled: Bool = true ) {
93
+ automaticDiffingEnabled: Bool = true ,
94
+ lightweightDiffing: Bool = false
95
+ ) {
90
96
self . _tableViewModel = tableViewModel
91
97
self . tableView = tableView
92
98
self . _automaticDiffingEnabled = automaticDiffingEnabled
99
+ self . _lightweightDiffing = lightweightDiffing
93
100
self . _shouldDeselectUponSelection = shouldDeselectUponSelection
94
101
super. init ( )
95
102
tableView. dataSource = self
@@ -182,40 +189,56 @@ open class TableViewDriver: NSObject {
182
189
183
190
guard let newModel = newModel else { return }
184
191
185
- if self . _automaticDiffingEnabled {
192
+ if self . _automaticDiffingEnabled, self . _lightweightDiffing {
193
+ let old = oldModel? . sectionModels. reduce ( into: 0 ) { $0 += $1. cellViewModels. count }
194
+ let new = newModel. sectionModels. reduce ( into: 0 ) { $0 += $1. cellViewModels. count }
186
195
187
- let visibleIndexPaths = tableView. indexPathsForVisibleRows ?? [ ]
188
- let old : [ DiffableTableSectionViewModel ] = oldModel? . sectionModelsForDiffing ( inVisibleIndexPaths: visibleIndexPaths) ?? [ ]
189
- let changeset = StagedChangeset (
190
- source: old,
191
- target: newModel. sectionModelsForDiffing ( inVisibleIndexPaths: visibleIndexPaths)
192
- )
193
- if changeset. isEmpty {
194
- self . _tableViewModel = newModel
196
+ self . _tableViewModel = newModel
197
+ if old == new {
198
+ self . refreshViews ( refreshContext: . contentOnly)
195
199
} else {
196
- self . tableView. reload (
197
- using: changeset,
198
- deleteSectionsAnimation: self . deletionAnimation,
199
- insertSectionsAnimation: self . insertionAnimation,
200
- reloadSectionsAnimation: self . insertionAnimation,
201
- deleteRowsAnimation: self . deletionAnimation,
202
- insertRowsAnimation: self . insertionAnimation,
203
- reloadRowsAnimation: self . insertionAnimation
204
- ) {
205
- self . _tableViewModel = $0. makeTableViewModel ( sectionIndexTitles: oldModel? . sectionIndexTitles)
200
+ // We need to call reloadData here to ensure UITableView is in-sync with the data source before we start
201
+ // making calls to access visible cells. In the automatic diffing case, this is handled by calls to
202
+ // beginUpdates() endUpdates()
203
+ self . tableView. reloadData ( )
204
+ self . refreshViews ( )
205
+ }
206
+ } else {
207
+ if self . _automaticDiffingEnabled {
208
+
209
+ let visibleIndexPaths = tableView. indexPathsForVisibleRows ?? [ ]
210
+ let old : [ DiffableTableSectionViewModel ] = oldModel? . sectionModelsForDiffing ( inVisibleIndexPaths: visibleIndexPaths) ?? [ ]
211
+ let changeset = StagedChangeset (
212
+ source: old,
213
+ target: newModel. sectionModelsForDiffing ( inVisibleIndexPaths: visibleIndexPaths)
214
+ )
215
+ if changeset. isEmpty {
216
+ self . _tableViewModel = newModel
217
+ } else {
218
+ self . tableView. reload (
219
+ using: changeset,
220
+ deleteSectionsAnimation: self . deletionAnimation,
221
+ insertSectionsAnimation: self . insertionAnimation,
222
+ reloadSectionsAnimation: self . insertionAnimation,
223
+ deleteRowsAnimation: self . deletionAnimation,
224
+ insertRowsAnimation: self . insertionAnimation,
225
+ reloadRowsAnimation: self . insertionAnimation
226
+ ) {
227
+ self . _tableViewModel = $0. makeTableViewModel ( sectionIndexTitles: oldModel? . sectionIndexTitles)
228
+ }
229
+ self . _tableViewModel = newModel
206
230
}
231
+ // always refresh visible cells, in case some
232
+ // state changed that isn't captured by the diff
233
+ self . refreshViews ( refreshContext: . contentOnly)
234
+ } else {
207
235
self . _tableViewModel = newModel
236
+ // We need to call reloadData here to ensure UITableView is in-sync with the data source before we start
237
+ // making calls to access visible cells. In the automatic diffing case, this is handled by calls to
238
+ // beginUpdates() endUpdates()
239
+ self . tableView. reloadData ( )
240
+ self . refreshViews ( )
208
241
}
209
- // always refresh visible cells, in case some
210
- // state changed that isn't captured by the diff
211
- self . refreshViews ( refreshContext: . contentOnly)
212
- } else {
213
- self . _tableViewModel = newModel
214
- // We need to call reloadData here to ensure UITableView is in-sync with the data source before we start
215
- // making calls to access visible cells. In the automatic diffing case, this is handled by calls to
216
- // beginUpdates() endUpdates()
217
- self . tableView. reloadData ( )
218
- self . refreshViews ( )
219
242
}
220
243
}
221
244
0 commit comments