Replacing UITableViewDiffableDataSource with DifferenceKit
This commit is contained in:
parent
7d838e4e07
commit
1c86331d7d
@ -184,15 +184,7 @@ class Vehicle: Object, Decodable, Identifiable, Differentiable, Cloneable {
|
|||||||
var osagoContracts = List<Osago>()
|
var osagoContracts = List<Osago>()
|
||||||
var ads = List<VehicleAd>()
|
var ads = List<VehicleAd>()
|
||||||
|
|
||||||
var identifier: String = ""
|
var differenceIdentifier: String { self.number }
|
||||||
var id: String {
|
|
||||||
if self.identifier.isEmpty {
|
|
||||||
self.identifier = self.number
|
|
||||||
}
|
|
||||||
return self.identifier
|
|
||||||
}
|
|
||||||
|
|
||||||
var differenceIdentifier: String { id }
|
|
||||||
|
|
||||||
func isContentEqual(to source: Vehicle) -> Bool {
|
func isContentEqual(to source: Vehicle) -> Bool {
|
||||||
return self == source
|
return self == source
|
||||||
@ -266,27 +258,19 @@ class Vehicle: Object, Decodable, Identifiable, Differentiable, Cloneable {
|
|||||||
if let ads = try container.decodeIfPresent([VehicleAd].self, forKey: .ads) {
|
if let ads = try container.decodeIfPresent([VehicleAd].self, forKey: .ads) {
|
||||||
self.ads.append(objectsIn: ads)
|
self.ads.append(objectsIn: ads)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.identifier = self.number
|
|
||||||
}
|
}
|
||||||
|
|
||||||
required init() {
|
required init() {
|
||||||
super.init()
|
super.init()
|
||||||
self.identifier = self.number
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init(_ number: String) {
|
init(_ number: String) {
|
||||||
self.identifier = number
|
|
||||||
self.number = number
|
self.number = number
|
||||||
self.addedDate = Date().timeIntervalSince1970
|
self.addedDate = Date().timeIntervalSince1970
|
||||||
self.updatedDate = self.addedDate
|
self.updatedDate = self.addedDate
|
||||||
}
|
}
|
||||||
|
|
||||||
func getNumber() -> String {
|
func getNumber() -> String {
|
||||||
if self.identifier.isEmpty {
|
|
||||||
self.identifier = self.number
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.number
|
return self.number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,39 +5,25 @@ import ExceptionCatcher
|
|||||||
|
|
||||||
typealias FilterPredicate<T> = (T) -> Bool
|
typealias FilterPredicate<T> = (T) -> Bool
|
||||||
|
|
||||||
class RealmDiffableDataSourse<Item>: UITableViewDiffableDataSource<DateSection<Item>, Item> where Item: Hashable & ContentEquatable & ContentIdentifiable {
|
class RealmSectionedDataSource<Item,Cell>: NSObject, UITableViewDataSource
|
||||||
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
where Item: Object & Identifiable & Dated & Differentiable & Cloneable,
|
||||||
return snapshot().sectionIdentifiers[section].header
|
Cell: UITableViewCell & ConfigurableCell,
|
||||||
}
|
Cell.Item == Item {
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class RealmSectionedDataSource<Item,Cell> where Item: Object & Identifiable & Dated & Differentiable & Cloneable, Cell: UITableViewCell & ConfigurableCell, Cell.Item == Item {
|
|
||||||
|
|
||||||
private var tv: UITableView
|
private var tv: UITableView
|
||||||
private var data: Results<Item>
|
private var data: Results<Item>
|
||||||
private var notificationToken: NotificationToken?
|
private var notificationToken: NotificationToken?
|
||||||
private var sections: [DateSection<Item>] = []
|
private var sections: [DateSection<Item>] = []
|
||||||
private var cellIdentifier: String
|
private var cellIdentifier: String
|
||||||
private var lastUpdateTime = Date()
|
|
||||||
private var dataSource: RealmDiffableDataSourse<Item>!
|
|
||||||
private var filterPredicate: FilterPredicate<Item>?
|
private var filterPredicate: FilterPredicate<Item>?
|
||||||
|
|
||||||
init(table: UITableView, data: Results<Item>, cellIdentifier: String = String(describing: Cell.self)) {
|
init(table: UITableView, data: Results<Item>, cellIdentifier: String = String(describing: Cell.self)) {
|
||||||
self.tv = table
|
self.tv = table
|
||||||
self.data = data
|
self.data = data
|
||||||
self.cellIdentifier = cellIdentifier
|
self.cellIdentifier = cellIdentifier
|
||||||
|
super.init()
|
||||||
self.dataSource = RealmDiffableDataSourse<Item>(tableView: table) { tv, ip, model -> UITableViewCell? in
|
self.tv.dataSource = self
|
||||||
let cell = tv.dequeueReusableCell(withIdentifier: self.cellIdentifier, for: ip) as? Cell
|
self.tv.reloadData()
|
||||||
cell?.configure(with: model)
|
|
||||||
return cell
|
|
||||||
}
|
|
||||||
self.dataSource.defaultRowAnimation = .fade
|
|
||||||
self.tv.dataSource = self.dataSource
|
|
||||||
|
|
||||||
self.notificationToken = self.data.observe { changes in
|
self.notificationToken = self.data.observe { changes in
|
||||||
switch changes {
|
switch changes {
|
||||||
@ -50,6 +36,30 @@ class RealmSectionedDataSource<Item,Cell> where Item: Object & Identifiable & Da
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - UITableViewDataSource
|
||||||
|
|
||||||
|
func numberOfSections(in tableView: UITableView) -> Int {
|
||||||
|
return self.sections.count
|
||||||
|
}
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||||
|
return self.sections[section].elements.count
|
||||||
|
}
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||||
|
guard let cell = tableView.dequeueReusableCell(withIdentifier: self.cellIdentifier, for: indexPath) as? Cell else {
|
||||||
|
return UITableViewCell()
|
||||||
|
}
|
||||||
|
|
||||||
|
let item = self.sections[indexPath.section].elements[indexPath.row]
|
||||||
|
cell.configure(with: item)
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
||||||
|
return self.sections[section].header
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
|
|
||||||
@ -62,13 +72,12 @@ class RealmSectionedDataSource<Item,Cell> where Item: Object & Identifiable & Da
|
|||||||
if let predicate = self.filterPredicate {
|
if let predicate = self.filterPredicate {
|
||||||
items = items.filter(predicate)
|
items = items.filter(predicate)
|
||||||
}
|
}
|
||||||
self.sections = items.groupedByDate()
|
|
||||||
var snapshot = NSDiffableDataSourceSnapshot<DateSection<Item>, Item>()
|
let newSections = items.groupedByDate()
|
||||||
snapshot.appendSections(self.sections)
|
let changeset = StagedChangeset(source: self.sections, target: newSections)
|
||||||
for section in self.sections {
|
self.tv.reload(using: changeset, with: animated ? .fade : .none) { newSects in
|
||||||
snapshot.appendItems(section.elements, toSection: section)
|
self.sections = newSects
|
||||||
}
|
}
|
||||||
self.dataSource.apply(snapshot, animatingDifferences: animated, completion: nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func setFilterPredicate(_ predicate: FilterPredicate<Item>?) {
|
func setFilterPredicate(_ predicate: FilterPredicate<Item>?) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user