Skip to content

Commit 2e7f8ae

Browse files
feat(TableViewDriver): allow lightweightDiffing
1 parent 1c04800 commit 2e7f8ae

File tree

3 files changed

+59
-31
lines changed

3 files changed

+59
-31
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ The changelog for `ReactiveLists`. Also see the [releases](https://github.com/pl
55
------
66

77
NEXT
8+
----
9+
0.8.3
10+
-----
11+
- Added `lightweightDiffing` option to `TableViewDriver`
12+
813
----
914
0.8.2
1015
-----

ReactiveLists.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = "ReactiveLists"
3-
s.version = "0.8.2"
3+
s.version = "0.8.3"
44

55
s.summary = "React-like API for UITableView and UICollectionView"
66
s.homepage = "https://github.com/plangrid/ReactiveLists"

Sources/TableViewDriver.swift

Lines changed: 53 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ open class TableViewDriver: NSObject {
7272

7373
private let _automaticDiffingEnabled: Bool
7474

75+
private let _lightweightDiffing: Bool
76+
7577
/// Initializes a data source that drives a `UITableView` based on a `TableViewModel`.
7678
///
7779
/// - Parameters:
@@ -82,14 +84,19 @@ open class TableViewDriver: NSObject {
8284
/// - automaticDiffingEnabled: defines whether or not this data source updates the table
8385
/// view automatically when cells/sections are moved/inserted/deleted.
8486
/// Defaults to `true`.
87+
/// - lightweightDiffing: when enabled, simply diff the count of rows rather than generating full changesets.
88+
/// Defaults to `false`.
8589
public init(
8690
tableView: UITableView,
8791
tableViewModel: TableViewModel? = nil,
8892
shouldDeselectUponSelection: Bool = true,
89-
automaticDiffingEnabled: Bool = true) {
93+
automaticDiffingEnabled: Bool = true,
94+
lightweightDiffing: Bool = false
95+
) {
9096
self._tableViewModel = tableViewModel
9197
self.tableView = tableView
9298
self._automaticDiffingEnabled = automaticDiffingEnabled
99+
self._lightweightDiffing = lightweightDiffing
93100
self._shouldDeselectUponSelection = shouldDeselectUponSelection
94101
super.init()
95102
tableView.dataSource = self
@@ -182,40 +189,56 @@ open class TableViewDriver: NSObject {
182189

183190
guard let newModel = newModel else { return }
184191

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 }
186195

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)
195199
} 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
206230
}
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 {
207235
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()
208241
}
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()
219242
}
220243
}
221244

0 commit comments

Comments
 (0)