Created
July 20, 2015 17:41
-
-
Save pmairoldi/4bbb093820355eb5eb0b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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