I am currently facing troubles using UITableViewDiffableDataSource
.
I would like to give a shot to this new feature, so I went on many tutorials on the net, but none of them seems to answer my issue.
In my current viewController I have a UITableView
, with 3 different objects (with different types each), but the UITableViewDiffableDataSource
is strongly typed to one.
Like: dataSource = UITableViewDiffableDataSource <SectionType, ItemType>
All my sections are fed with something like
func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return bigObject.ObjectsOfType1.count
} else if section == 1 {
return bigObject.ObjectsOfType2.count
} else {
return bigObject.ObjectsOfType3.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as! CustomTableViewCell
if indexPath.section == 0 {
cell.buildWithFirstObject(obj: bigObject.ObjectsOfType1[indexPath.row])
} else if indexPath.section == 1 {
cell.buildWithFirstObject(obj: bigObject.ObjectsOfType2[indexPath.row])
} else {
cell.buildWithFirstObject(obj: bigObject.ObjecstOfType3[indexPath.row])
}
}
Is there a trick to use diffable dataSource in my case ?
Any help is appreciated ! Thank you for reading me :)
For the simplest approach, I would suggest using AnyHashable
for the item identifier and enum
for the section identifier. I would avoid using an enumeration for the item identifier because it can quickly get out of hand constantly employing switches just to unwrap generic enumerations into custom types, which is not only onerous but doesn't read well at all.
// MARK: SECTION IDENTIFIERS
private enum Section {
case title
case kiwis
case mangos
}
// MARK: DATA MODELS
private struct Title: Hashable {}
private struct Kiwi: Hashable {
let identifier = UUID().uuidString
func hash(into hasher: inout Hasher) {
hasher.combine(identifier)
}
static func == (lhs: Kiwi, rhs: Kiwi) -> Bool {
return lhs.identifier == rhs.identifier
}
}
private struct Mango: Hashable {
let identifier = UUID().uuidString
func hash(into hasher: inout Hasher) {
hasher.combine(identifier)
}
static func == (lhs: Mango, rhs: Mango) -> Bool {
return lhs.identifier == rhs.identifier
}
}
// MARK: DATA SOURCE
private var dataSource: UITableViewDiffableDataSource<Section, AnyHashable>!
dataSource = UITableViewDiffableDataSource(tableView: tableView, cellProvider: { (tableView, indexPath, item) -> UITableViewCell? in
switch item {
case is Title:
return TitleCell()
case let item as Kiwi:
let cell = tableView.dequeueReusableCell(withIdentifier: KiwiCell.identifer, for: indexPath) as? KiwiCell
cell?.label.text = item.identifier
return cell
case let item as Mango:
let cell = tableView.dequeueReusableCell(withIdentifier: MangoCell.identifier, for: indexPath) as? MangoCell
cell?.label.text = item.identifier
return cell
default:
return nil
}
})
// MARK: USAGE
var initialSnapshot = NSDiffableDataSourceSnapshot<Section, AnyHashable>()
initialSnapshot.appendSections([.title, .kiwis, .mangos])
initialSnapshot.appendItems([Title()], toSection: .title)
initialSnapshot.appendItems([k1, k2, k3], toSection: .kiwis)
initialSnapshot.appendItems([m1, m2, m3], toSection: .mangos)
self.dataSource.apply(initialSnapshot, animatingDifferences: false)