Skip to content

Instantly share code, notes, and snippets.

@MatrixSenpai
Created April 22, 2019 22:08
Show Gist options
  • Save MatrixSenpai/19d4227f0a71d720da967fc8b48ced14 to your computer and use it in GitHub Desktop.
Save MatrixSenpai/19d4227f0a71d720da967fc8b48ced14 to your computer and use it in GitHub Desktop.
protocol BaseTableType where Self: UITableView {
associatedtype CellType: Configurable
associatedtype ItemType: Decodable
}
class BaseTable<T: Configurable>: UITableView, BaseTableType, UITableViewDelegate {
typealias CellType = T
typealias ItemType = T.ItemType
private let bag = DisposeBag()
private var itemsDataSource: RxTableViewSectionedReloadDataSource<SectionModel<String, ItemType>>
private var cellHeight : CGFloat = 50
var selectionCallback: ((_ table: UITableView, _ index: IndexPath, _ cell: CellType) -> Void)?
var source: BehaviorRelay<[String: [ItemType]]> = BehaviorRelay<[String: [ItemType]]>(value: [:])
var sortedSource = BehaviorRelay<[(String, [ItemType])]>(value: [])
convenience init() {
self.init(frame: .zero, style: .grouped)
}
convenience init(with dataSource: RxTableViewSectionedReloadDataSource<SectionModel<String, ItemType>>) {
self.init(frame: .zero, style: .grouped)
itemsDataSource = dataSource
}
override init(frame: CGRect, style: UITableView.Style) {
itemsDataSource = RxTableViewSectionedReloadDataSource<SectionModel<String, ItemType>>(configureCell: { (source, table, index, item) -> UITableViewCell in
let cell = table.dequeueReusableCell(withIdentifier: CellType.identifier, for: index) as! CellType
cell.selectionStyle = .none
cell.configure(with: item)
return cell
}, titleForHeaderInSection: { source, index in
guard !source[index].model.isEmpty else { return nil }
return source[index].model
})
super.init(frame: frame, style: style)
register(CellType.self, forCellReuseIdentifier: CellType.identifier)
backgroundColor = .clear
separatorStyle = .none
rx.setDelegate(self).disposed(by: bag)
sortedSource.compactMap { source in
return source.map { inner in
return SectionModel<String, ItemType>(model: inner.0, items: inner.1)
}
}.bind(to: rx.items(dataSource: itemsDataSource))
.disposed(by: bag)
}
func setHeight(to h: CGFloat) {
cellHeight = h
reloadData()
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return cellHeight
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectionCallback?(tableView, indexPath, tableView.cellForRow(at: indexPath) as! CellType)
}
@available(*, unavailable)
required init?(coder aDecoder: NSCoder) {
fatalError()
}
}
protocol Configurable where Self: UITableViewCell {
associatedtype ItemType: Decodable
static var identifier: String { get }
var item: ItemType? { get set }
func configure(with item: ItemType)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment