Skip to content

Instantly share code, notes, and snippets.

@pranjalsatija
Last active December 31, 2020 00:06
Show Gist options
  • Save pranjalsatija/e638a0d914042684d9dcc52448178dee to your computer and use it in GitHub Desktop.
Save pranjalsatija/e638a0d914042684d9dcc52448178dee to your computer and use it in GitHub Desktop.
A simple implementation of UITableViewDescriptor.
class UITableViewDescriptor: NSObject {
var tableView: UITableView? {
didSet {
configureBindings()
}
}
private var dataSource: UITableViewDiffableDataSource<Int, AnyHashable>!
private var sections = [UITableViewSection]()
private let sectionsPublisher: AnyPublisher<[UITableViewSection], Never>
private var subscriptions = Set<AnyCancellable>()
convenience init(sections: [UITableViewSection]) {
self.init(sections: Just(sections).eraseToAnyPublisher())
}
init<T: Publisher>(sections: T) where T.Output == [UITableViewSection], T.Failure == Never {
self.sectionsPublisher = sections.eraseToAnyPublisher()
}
func updateSnapshot() {
var snapshot = NSDiffableDataSourceSnapshot<Int, AnyHashable>()
snapshot.appendSections(sections.map { $0.sectionIndex })
for section in sections {
snapshot.appendItems(section.items, toSection: section.sectionIndex)
}
dataSource.apply(snapshot, animatingDifferences: true)
}
private func configureBindings() {
guard let tableView = self.tableView else { return }
dataSource = UITableViewDiffableDataSource<Int, AnyHashable>(
tableView: tableView,
cellProvider: {(tableView, indexPath, data) in
self.sections[indexPath.section].cellForRow(in: tableView, indexPath: indexPath)
}
)
tableView.dataSource = self.dataSource
sectionsPublisher.sink {
self.sections = $0
self.sections.enumerated().forEach { $1.attach(to: self, sectionIndex: $0) }
self.updateSnapshot()
}.store(in: &subscriptions)
}
}
extension UITableViewDescriptor: UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
sections[section].numberOfRows()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment