Skip to content

Instantly share code, notes, and snippets.

@pmairoldi
Created July 20, 2015 17:41
Show Gist options
  • Save pmairoldi/4bbb093820355eb5eb0b to your computer and use it in GitHub Desktop.
Save pmairoldi/4bbb093820355eb5eb0b to your computer and use it in GitHub Desktop.
import UIKit
import ReactiveCocoa
protocol Bindable {
func bind<T>(viewModel: T)
}
class TableViewBinding<T, E: ErrorType> {
//MARK: Properties
private let tableView: UITableView
private let dataSource: TableViewDataSource<T>
//MARK: Public API
init(tableView _tableView: UITableView, sourceSignal: SignalProducer<[T], E>, resuseIdentifier: String, selectionCommand: Action<T, Void, NoError>? = nil) {
tableView = _tableView
dataSource = TableViewDataSource(reuseIdentifier: resuseIdentifier, selectionCommand: selectionCommand)
tableView.dataSource = dataSource
tableView.delegate = dataSource
sourceSignal.on(next: { value in
self.dataSource.data.put(value)
self.tableView.reloadData()
}).start()
}
}
class TableViewDataSource<T>: NSObject, UITableViewDataSource, UITableViewDelegate {
private let reuseIdentifier: String
private let selectionCommand: Action<T, Void, NoError>?
let data = MutableProperty([T]())
init(reuseIdentifier _reuseIdentifier: String, selectionCommand _selectionCommand: Action<T, Void, NoError>? = nil) {
reuseIdentifier = _reuseIdentifier
selectionCommand = _selectionCommand
}
//MARK: Datasource Methods
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.value.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(self.reuseIdentifier, forIndexPath: indexPath)
let item = data.value[indexPath.row]
if let reactiveView = cell as? Bindable {
reactiveView.bind(item)
}
return cell
}
//MARK: Delegate methods
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 44
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
guard let selectionCommand = selectionCommand else {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
return
}
let item = data.value[indexPath.row]
selectionCommand
.apply(item)
.on(completed: { tableView.deselectRowAtIndexPath(indexPath, animated: true) })
.start()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment