From 7208a8d1cc4f8eb032b572af13f0ca4146a23a4d Mon Sep 17 00:00:00 2001 From: Krunoslav Zaher Date: Sun, 21 Aug 2016 15:09:14 +0200 Subject: [PATCH] Improves deprecation messages for table and collection views. #841 --- .../Common/SectionedViewDataSourceType.swift | 17 +- ...ollectionViewReactiveArrayDataSource.swift | 2 +- .../RxTableViewReactiveArrayDataSource.swift | 2 +- RxCocoa/iOS/UICollectionView+Rx.swift | 282 ++++++++--------- RxCocoa/iOS/UITableView+Rx.swift | 298 +++++++++--------- .../CollectionViewSectionedDataSource.swift | 19 +- .../TableViewSectionedDataSource.swift | 23 +- ...leViewExampleSectionedViewController.swift | 2 +- .../PartialUpdatesViewController.swift | 2 +- .../SectionedViewDataSourceMock.swift | 2 +- .../UICollectionView+RxTests.swift | 2 +- Tests/RxCocoaTests/UITableView+RxTests.swift | 2 +- 12 files changed, 336 insertions(+), 317 deletions(-) diff --git a/RxCocoa/Common/SectionedViewDataSourceType.swift b/RxCocoa/Common/SectionedViewDataSourceType.swift index d1ac49c8..96891879 100644 --- a/RxCocoa/Common/SectionedViewDataSourceType.swift +++ b/RxCocoa/Common/SectionedViewDataSourceType.swift @@ -20,5 +20,20 @@ public protocol SectionedViewDataSourceType { - parameter indexPath: Model index path - returns: Model at index path. */ - func modelAtIndexPath(_ indexPath: IndexPath) throws -> Any + func model(_ indexPath: IndexPath) throws -> Any +} + +extension SectionedViewDataSourceType { + /** + Returns model at index path. + + In case data source doesn't contain any sections when this method is being called, `RxCocoaError.ItemsNotYetBound(object: self)` is thrown. + + - parameter indexPath: Model index path + - returns: Model at index path. + */ + @available(*, deprecated, renamed: "model(_:)") + func model(_ indexPath: IndexPath) throws -> Any { + return try self.model(indexPath) + } } diff --git a/RxCocoa/iOS/DataSources/RxCollectionViewReactiveArrayDataSource.swift b/RxCocoa/iOS/DataSources/RxCollectionViewReactiveArrayDataSource.swift index ffa635e6..1cbf5825 100644 --- a/RxCocoa/iOS/DataSources/RxCollectionViewReactiveArrayDataSource.swift +++ b/RxCocoa/iOS/DataSources/RxCollectionViewReactiveArrayDataSource.swift @@ -72,7 +72,7 @@ class RxCollectionViewReactiveArrayDataSource return itemModels?[index] } - func modelAtIndexPath(_ indexPath: IndexPath) throws -> Any { + func model(_ indexPath: IndexPath) throws -> Any { precondition(indexPath.section == 0) guard let item = itemModels?[indexPath.item] else { throw RxCocoaError.itemsNotYetBound(object: self) diff --git a/RxCocoa/iOS/DataSources/RxTableViewReactiveArrayDataSource.swift b/RxCocoa/iOS/DataSources/RxTableViewReactiveArrayDataSource.swift index 37bba0a1..8ec0935a 100644 --- a/RxCocoa/iOS/DataSources/RxTableViewReactiveArrayDataSource.swift +++ b/RxCocoa/iOS/DataSources/RxTableViewReactiveArrayDataSource.swift @@ -70,7 +70,7 @@ class RxTableViewReactiveArrayDataSource return itemModels?[index] } - func modelAtIndexPath(_ indexPath: IndexPath) throws -> Any { + func model(_ indexPath: IndexPath) throws -> Any { precondition(indexPath.section == 0) guard let item = itemModels?[indexPath.item] else { throw RxCocoaError.itemsNotYetBound(object: self) diff --git a/RxCocoa/iOS/UICollectionView+Rx.swift b/RxCocoa/iOS/UICollectionView+Rx.swift index 32fa3064..80716b1a 100644 --- a/RxCocoa/iOS/UICollectionView+Rx.swift +++ b/RxCocoa/iOS/UICollectionView+Rx.swift @@ -17,43 +17,7 @@ import UIKit // Items extension Reactive where Base: UICollectionView { - - /** - Binds sequences of elements to collection view items. - - - parameter source: Observable sequence of items. - - parameter cellFactory: Transform between sequence elements and view cells. - - returns: Disposable object that can be used to unbind. - - Example - - let items = Observable.just([ - 1, - 2, - 3 - ]) - items - .bindTo(collectionView.rx.itemsWithCellFactory) { (collectionView, row, element) in - let indexPath = IndexPath(forItem: row, inSection: 0) - let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! NumberCell - cell.value?.text = "\(element) @ \(row)" - return cell - } - .addDisposableTo(disposeBag) - */ - @available(*, deprecated, renamed: "items(source:cellFactory:)") - public func rx_itemsWithCellFactory - (_ source: O) - -> (_ cellFactory: @escaping (UICollectionView, Int, S.Iterator.Element) -> UICollectionViewCell) - -> Disposable where O.E == S { - return { cellFactory in - let dataSource = RxCollectionViewReactiveArrayDataSourceSequenceWrapper(cellFactory: cellFactory) - return self.items(dataSource: dataSource)(source) - } - - } - /** Binds sequences of elements to collection view items. @@ -79,7 +43,7 @@ extension Reactive where Base: UICollectionView { .addDisposableTo(disposeBag) */ public func items - (source: O) + (_ source: O) -> (_ cellFactory: @escaping (UICollectionView, Int, S.Iterator.Element) -> UICollectionViewCell) -> Disposable where O.E == S { return { cellFactory in @@ -92,49 +56,6 @@ extension Reactive where Base: UICollectionView { /** Binds sequences of elements to collection view items. - - parameter cellIdentifier: Identifier used to dequeue cells. - - parameter source: Observable sequence of items. - - parameter configureCell: Transform between sequence elements and view cells. - - parameter cellType: Type of table view cell. - - returns: Disposable object that can be used to unbind. - - Example - - let items = Observable.just([ - 1, - 2, - 3 - ]) - - items - .bindTo(collectionView.rx.itemsWithCellIdentifier("Cell", cellType: NumberCell.self)) { (row, element, cell) in - cell.value?.text = "\(element) @ \(row)" - } - .addDisposableTo(disposeBag) - */ - @available(*, deprecated, renamed: "items(cellIdentifier:cellType:source:configureCell:)") - public func rx_itemsWithCellIdentifier - (_ cellIdentifier: String, cellType: Cell.Type = Cell.self) - -> (_ source: O) - -> (_ configureCell: @escaping (Int, S.Iterator.Element, Cell) -> Void) - -> Disposable where O.E == S { - return { source in - return { configureCell in - let dataSource = RxCollectionViewReactiveArrayDataSourceSequenceWrapper { (cv, i, item) in - let indexPath = IndexPath(item: i, section: 0) - let cell = cv.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! Cell - configureCell(i, item, cell) - return cell - } - - return self.items(dataSource: dataSource)(source) - } - } - } - - /** - Binds sequences of elements to collection view items. - - parameter cellIdentifier: Identifier used to dequeue cells. - parameter source: Observable sequence of items. - parameter configureCell: Transform between sequence elements and view cells. @@ -175,63 +96,6 @@ extension Reactive where Base: UICollectionView { } - /** - Binds sequences of elements to collection view items using a custom reactive data used to perform the transformation. - - - parameter dataSource: Data source used to transform elements to view cells. - - parameter source: Observable sequence of items. - - returns: Disposable object that can be used to unbind. - - Example - - let dataSource = RxCollectionViewSectionedReloadDataSource>() - - let items = Observable.just([ - SectionModel(model: "First section", items: [ - 1.0, - 2.0, - 3.0 - ]), - SectionModel(model: "Second section", items: [ - 1.0, - 2.0, - 3.0 - ]), - SectionModel(model: "Third section", items: [ - 1.0, - 2.0, - 3.0 - ]) - ]) - - dataSource.configureCell = { (dataSource, cv, indexPath, element) in - let cell = cv.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! NumberCell - cell.value?.text = "\(element) @ row \(indexPath.row)" - return cell - } - - items - .bindTo(collectionView.rx.itemsWithDataSource(dataSource)) - .addDisposableTo(disposeBag) - */ - @available(*, deprecated, renamed: "items(dataSource:source:)") - public func rx_itemsWithDataSource< - DataSource: RxCollectionViewDataSourceType & UICollectionViewDataSource, - O: ObservableType> - (_ dataSource: DataSource) - -> (_ source: O) - -> Disposable where DataSource.Element == O.E - { - return { source in - return source.subscribeProxyDataSource(ofObject: self.base, dataSource: dataSource, retainDataSource: true) { [weak collectionView = self.base] (_: RxCollectionViewDataSourceProxy, event) -> Void in - guard let collectionView = collectionView else { - return - } - dataSource.collectionView(collectionView, observedEvent: event) - } - } - } - /** Binds sequences of elements to collection view items using a custom reactive data used to perform the transformation. @@ -283,7 +147,7 @@ extension Reactive where Base: UICollectionView { // data source is being bound. // This is needed because theoretically the data source subscription itself might // call `self.rx_delegate`. If that happens, it might cause weird side effects since - // setting data source will set delegate, and UITableView might get into a weird state. + // setting data source will set delegate, and UICollectionView might get into a weird state. // Therefore it's better to set delegate proxy first, just to be sure. _ = self.delegate // Strong reference is needed because data source is in use until result subscription is disposed @@ -385,7 +249,7 @@ extension Reactive where Base: UICollectionView { return Observable.empty() } - return Observable.just(try view.rx.modelAtIndexPath(indexPath)) + return Observable.just(try view.rx.model(indexPath)) } return ControlEvent(events: source) @@ -408,7 +272,7 @@ extension Reactive where Base: UICollectionView { return Observable.empty() } - return Observable.just(try view.rx.modelAtIndexPath(indexPath)) + return Observable.just(try view.rx.model(indexPath)) } return ControlEvent(events: source) @@ -417,10 +281,10 @@ extension Reactive where Base: UICollectionView { /** Syncronous helper method for retrieving a model at indexPath through a reactive data source */ - public func modelAtIndexPath(_ indexPath: IndexPath) throws -> T { + public func model(_ indexPath: IndexPath) throws -> T { let dataSource: SectionedViewDataSourceType = castOrFatalError(self.dataSource.forwardToDelegate(), message: "This method only works in case one of the `rx.itemsWith*` methods was used.") - let element = try dataSource.modelAtIndexPath(indexPath) + let element = try dataSource.model(indexPath) return element as! T } @@ -447,3 +311,137 @@ extension Reactive where Base: UICollectionView { } } #endif + +extension UICollectionView { + + /** + Binds sequences of elements to collection view items. + + - parameter cellIdentifier: Identifier used to dequeue cells. + - parameter source: Observable sequence of items. + - parameter configureCell: Transform between sequence elements and view cells. + - parameter cellType: Type of table view cell. + - returns: Disposable object that can be used to unbind. + + Example + + let items = Observable.just([ + 1, + 2, + 3 + ]) + + items + .bindTo(collectionView.rx.items(cellIdentifier: "Cell", cellType: NumberCell.self)) { (row, element, cell) in + cell.value?.text = "\(element) @ \(row)" + } + .addDisposableTo(disposeBag) + */ + @available(*, deprecated, renamed: "items(cellIdentifier:cellType:_:_:)") + public func rx_itemsWithCellIdentifier + (_ cellIdentifier: String, cellType: Cell.Type = Cell.self) + -> (_ source: O) + -> (_ configureCell: @escaping (Int, S.Iterator.Element, Cell) -> Void) + -> Disposable where O.E == S { + return { source in + return { configureCell in + return self.rx.items(cellIdentifier: cellIdentifier, cellType: cellType)(source)(configureCell) + } + } + } + + + /** + Binds sequences of elements to collection view items. + + - parameter source: Observable sequence of items. + - parameter cellFactory: Transform between sequence elements and view cells. + - returns: Disposable object that can be used to unbind. + + Example + + let items = Observable.just([ + 1, + 2, + 3 + ]) + + items + .bindTo(collectionView.rx.items) { (collectionView, row, element) in + let indexPath = IndexPath(forItem: row, inSection: 0) + let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! NumberCell + cell.value?.text = "\(element) @ \(row)" + return cell + } + .addDisposableTo(disposeBag) + */ + @available(*, deprecated, renamed: "items(_:_:)") + public func rx_itemsWithCellFactory + (_ source: O) + -> (_ cellFactory: @escaping (UICollectionView, Int, S.Iterator.Element) -> UICollectionViewCell) + -> Disposable where O.E == S { + return { cellFactory in + return self.rx.items(source)(cellFactory) + } + } + + /** + Binds sequences of elements to collection view items using a custom reactive data used to perform the transformation. + + - parameter dataSource: Data source used to transform elements to view cells. + - parameter source: Observable sequence of items. + - returns: Disposable object that can be used to unbind. + + Example + + let dataSource = RxCollectionViewSectionedReloadDataSource>() + + let items = Observable.just([ + SectionModel(model: "First section", items: [ + 1.0, + 2.0, + 3.0 + ]), + SectionModel(model: "Second section", items: [ + 1.0, + 2.0, + 3.0 + ]), + SectionModel(model: "Third section", items: [ + 1.0, + 2.0, + 3.0 + ]) + ]) + + dataSource.configureCell = { (dataSource, cv, indexPath, element) in + let cell = cv.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! NumberCell + cell.value?.text = "\(element) @ row \(indexPath.row)" + return cell + } + + items + .bindTo(collectionView.rx.items(dataSource: dataSource)) + .addDisposableTo(disposeBag) + */ + @available(*, deprecated, renamed: "items(dataSource:_:)") + public func rx_itemsWithDataSource< + DataSource: RxCollectionViewDataSourceType & UICollectionViewDataSource, + O: ObservableType> + (_ dataSource: DataSource) + -> (_ source: O) + -> Disposable where DataSource.Element == O.E + { + return { source in + return self.rx.items(dataSource: dataSource)(source) + } + } + + /** + Syncronous helper method for retrieving a model at indexPath through a reactive data source + */ + @available(*, deprecated, renamed: "rx.model(_:)") + public func model(_ indexPath: IndexPath) throws -> T { + return try self.rx.model(indexPath) + } +} diff --git a/RxCocoa/iOS/UITableView+Rx.swift b/RxCocoa/iOS/UITableView+Rx.swift index f2bf1db5..8fdeea8b 100644 --- a/RxCocoa/iOS/UITableView+Rx.swift +++ b/RxCocoa/iOS/UITableView+Rx.swift @@ -17,43 +17,6 @@ import UIKit // Items extension Reactive where Base: UITableView { - - /** - Binds sequences of elements to table view rows. - - - parameter source: Observable sequence of items. - - parameter cellFactory: Transform between sequence elements and view cells. - - returns: Disposable object that can be used to unbind. - - Example: - - let items = Observable.just([ - "First Item", - "Second Item", - "Third Item" - ]) - - items - .bindTo(tableView.rx.itemsWithCellFactory) { (tableView, row, element) in - let cell = tableView.dequeueReusableCellWithIdentifier("Cell")! - cell.textLabel?.text = "\(element) @ row \(row)" - return cell - } - .addDisposableTo(disposeBag) - - */ - @available(*, deprecated, renamed: "items(source:cellFactory:)") - public func rx_itemsWithCellFactory - (_ source: O) - -> (_ cellFactory: @escaping (UITableView, Int, S.Iterator.Element) -> UITableViewCell) - -> Disposable - where O.E == S { - return { cellFactory in - let dataSource = RxTableViewReactiveArrayDataSourceSequenceWrapper(cellFactory: cellFactory) - - return self.items(dataSource: dataSource)(source) - } - } /** Binds sequences of elements to table view rows. @@ -71,7 +34,7 @@ extension Reactive where Base: UITableView { ]) items - .bindTo(tableView.items) { (tableView, row, element) in + .bindTo(tableView.rx.items) { (tableView, row, element) in let cell = tableView.dequeueReusableCellWithIdentifier("Cell")! cell.textLabel?.text = "\(element) @ row \(row)" return cell @@ -93,49 +56,6 @@ extension Reactive where Base: UITableView { /** Binds sequences of elements to table view rows. - - parameter cellIdentifier: Identifier used to dequeue cells. - - parameter source: Observable sequence of items. - - parameter configureCell: Transform between sequence elements and view cells. - - parameter cellType: Type of table view cell. - - returns: Disposable object that can be used to unbind. - - Example: - - let items = Observable.just([ - "First Item", - "Second Item", - "Third Item" - ]) - - items - .bindTo(tableView.rx.itemsWithCellIdentifier("Cell", cellType: UITableViewCell.self)) { (row, element, cell) in - cell.textLabel?.text = "\(element) @ row \(row)" - } - .addDisposableTo(disposeBag) - */ - @available(*, deprecated, renamed: "items(cellIdentifier:cellType:source:configureCell:)") - public func rx_itemsWithCellIdentifier - (_ cellIdentifier: String, cellType: Cell.Type = Cell.self) - -> (_ source: O) - -> (_ configureCell: @escaping (Int, S.Iterator.Element, Cell) -> Void) - -> Disposable - where O.E == S { - return { source in - return { configureCell in - let dataSource = RxTableViewReactiveArrayDataSourceSequenceWrapper { (tv, i, item) in - let indexPath = IndexPath(item: i, section: 0) - let cell = tv.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! Cell - configureCell(i, item, cell) - return cell - } - return self.items(dataSource: dataSource)(source) - } - } - } - - /** - Binds sequences of elements to table view rows. - - parameter cellIdentifier: Identifier used to dequeue cells. - parameter source: Observable sequence of items. - parameter configureCell: Transform between sequence elements and view cells. @@ -175,70 +95,6 @@ extension Reactive where Base: UITableView { } } - - /** - Binds sequences of elements to table view rows using a custom reactive data used to perform the transformation. - This method will retain the data source for as long as the subscription isn't disposed (result `Disposable` - being disposed). - In case `source` observable sequence terminates sucessfully, the data source will present latest element - until the subscription isn't disposed. - - - parameter dataSource: Data source used to transform elements to view cells. - - parameter source: Observable sequence of items. - - returns: Disposable object that can be used to unbind. - - Example - - let dataSource = RxTableViewSectionedReloadDataSource>() - - let items = Observable.just([ - SectionModel(model: "First section", items: [ - 1.0, - 2.0, - 3.0 - ]), - SectionModel(model: "Second section", items: [ - 1.0, - 2.0, - 3.0 - ]), - SectionModel(model: "Third section", items: [ - 1.0, - 2.0, - 3.0 - ]) - ]) - - dataSource.configureCell = { (dataSource, tv, indexPath, element) in - let cell = tv.dequeueReusableCellWithIdentifier("Cell")! - cell.textLabel?.text = "\(element) @ row \(indexPath.row)" - return cell - } - - items - .bindTo(tableView.rx.itemsWithDataSource(dataSource)) - .addDisposableTo(disposeBag) - */ - @available(*, deprecated, renamed: "items(dataSource:source:)") - public func rx_itemsWithDataSource< - DataSource: RxTableViewDataSourceType & UITableViewDataSource, - O: ObservableType> - (_ dataSource: DataSource) - -> (_ source: O) - -> Disposable - where DataSource.Element == O.E - { - return { source in - // There needs to be a strong retaining here because - return source.subscribeProxyDataSource(ofObject: self.base, dataSource: dataSource, retainDataSource: true) { [weak tableView = self.base] (_: RxTableViewDataSourceProxy, event) -> Void in - guard let tableView = tableView else { - return - } - dataSource.tableView(tableView, observedEvent: event) - } - } - } - /** Binds sequences of elements to table view rows using a custom reactive data used to perform the transformation. @@ -274,7 +130,7 @@ extension Reactive where Base: UITableView { ]) dataSource.configureCell = { (dataSource, tv, indexPath, element) in - let cell = tv.dequeueReusableCellWithIdentifier("Cell")! + let cell = tv.dequeueReusableCellWithIdentifier("Cell")! cell.textLabel?.text = "\(element) @ row \(indexPath.row)" return cell } @@ -477,7 +333,7 @@ extension Reactive where Base: UITableView { return Observable.empty() } - return Observable.just(try view.rx.modelAtIndexPath(indexPath)) + return Observable.just(try view.rx.model(indexPath)) } return ControlEvent(events: source) @@ -500,7 +356,7 @@ extension Reactive where Base: UITableView { return Observable.empty() } - return Observable.just(try view.rx.modelAtIndexPath(indexPath)) + return Observable.just(try view.rx.model(indexPath)) } return ControlEvent(events: source) @@ -509,10 +365,10 @@ extension Reactive where Base: UITableView { /** Synchronous helper method for retrieving a model at indexPath through a reactive data source. */ - public func modelAtIndexPath(_ indexPath: IndexPath) throws -> T { + public func model(_ indexPath: IndexPath) throws -> T { let dataSource: SectionedViewDataSourceType = castOrFatalError(self.dataSource.forwardToDelegate(), message: "This method only works in case one of the `rx.items*` methods was used.") - let element = try dataSource.modelAtIndexPath(indexPath) + let element = try dataSource.model(indexPath) return castOrFatalError(element) } @@ -540,3 +396,145 @@ extension Reactive where Base: UITableView { } } #endif + +// deprecated APIs +extension UITableView { + + /** + Binds sequences of elements to table view rows. + + - parameter source: Observable sequence of items. + - parameter cellFactory: Transform between sequence elements and view cells. + - returns: Disposable object that can be used to unbind. + + Example: + + let items = Observable.just([ + "First Item", + "Second Item", + "Third Item" + ]) + + items + .bindTo(tableView.rx.itemsWithCellFactory) { (tableView, row, element) in + let cell = tableView.dequeueReusableCellWithIdentifier("Cell")! + cell.textLabel?.text = "\(element) @ row \(row)" + return cell + } + .addDisposableTo(disposeBag) + + */ + @available(*, deprecated, renamed: "items(_:_:)") + public func rx_itemsWithCellFactory + (_ source: O) + -> (_ cellFactory: @escaping (UITableView, Int, S.Iterator.Element) -> UITableViewCell) + -> Disposable + where O.E == S { + return { cellFactory in + return self.rx.items(source)(cellFactory) + } + } + + /** + Binds sequences of elements to table view rows. + + - parameter cellIdentifier: Identifier used to dequeue cells. + - parameter source: Observable sequence of items. + - parameter configureCell: Transform between sequence elements and view cells. + - parameter cellType: Type of table view cell. + - returns: Disposable object that can be used to unbind. + + Example: + + let items = Observable.just([ + "First Item", + "Second Item", + "Third Item" + ]) + + items + .bindTo(tableView.rx.items(cellIdentifier: "Cell", cellType: UITableViewCell.self)) { (row, element, cell) in + cell.textLabel?.text = "\(element) @ row \(row)" + } + .addDisposableTo(disposeBag) + */ + @available(*, deprecated, renamed: "items(cellIdentifier:cellType:_:_:)") + public func rx_itemsWithCellIdentifier + (_ cellIdentifier: String, cellType: Cell.Type = Cell.self) + -> (_ source: O) + -> (_ configureCell: @escaping (Int, S.Iterator.Element, Cell) -> Void) + -> Disposable + where O.E == S { + return { source in + return { configureCell in + return self.rx.items(cellIdentifier: cellIdentifier, cellType: cellType)(source)(configureCell) + } + } + } + + /** + Binds sequences of elements to table view rows using a custom reactive data used to perform the transformation. + This method will retain the data source for as long as the subscription isn't disposed (result `Disposable` + being disposed). + In case `source` observable sequence terminates sucessfully, the data source will present latest element + until the subscription isn't disposed. + + - parameter dataSource: Data source used to transform elements to view cells. + - parameter source: Observable sequence of items. + - returns: Disposable object that can be used to unbind. + + Example + + let dataSource = RxTableViewSectionedReloadDataSource>() + + let items = Observable.just([ + SectionModel(model: "First section", items: [ + 1.0, + 2.0, + 3.0 + ]), + SectionModel(model: "Second section", items: [ + 1.0, + 2.0, + 3.0 + ]), + SectionModel(model: "Third section", items: [ + 1.0, + 2.0, + 3.0 + ]) + ]) + + dataSource.configureCell = { (dataSource, tv, indexPath, element) in + let cell = tv.dequeueReusableCellWithIdentifier("Cell")! + cell.textLabel?.text = "\(element) @ row \(indexPath.row)" + return cell + } + + items + .bindTo(tableView.rx.items(dataSoruce: dataSource)) + .addDisposableTo(disposeBag) + */ + @available(*, deprecated, renamed: "items(dataSource:_:)") + public func rx_itemsWithDataSource< + DataSource: RxTableViewDataSourceType & UITableViewDataSource, + O: ObservableType> + (_ dataSource: DataSource) + -> (_ source: O) + -> Disposable + where DataSource.Element == O.E + { + return { source in + return self.rx.items(dataSource: dataSource)(source) + } + } + + /** + Synchronous helper method for retrieving a model at indexPath through a reactive data source. + */ + @available(*, deprecated, renamed: "rx.model(_:)") + public func rx_modelAtIndexPath(_ indexPath: IndexPath) throws -> T { + return try self.rx.model(indexPath) + } + +} diff --git a/RxExample/RxDataSources/DataSources/CollectionViewSectionedDataSource.swift b/RxExample/RxDataSources/DataSources/CollectionViewSectionedDataSource.swift index ba984961..b1f68b03 100644 --- a/RxExample/RxDataSources/DataSources/CollectionViewSectionedDataSource.swift +++ b/RxExample/RxDataSources/DataSources/CollectionViewSectionedDataSource.swift @@ -99,17 +99,24 @@ public class CollectionViewSectionedDataSource return _sectionModels.map { Section(original: $0.model, items: $0.items) } } - public func sectionAtIndex(_ section: Int) -> S { + public subscript(section: Int) -> S { let sectionModel = self._sectionModels[section] return S(original: sectionModel.model, items: sectionModel.items) } - public func itemAtIndexPath(_ indexPath: IndexPath) -> I { - return self._sectionModels[indexPath.section].items[indexPath.item] + public subscript(indexPath: IndexPath) -> I { + get { + return self._sectionModels[indexPath.section].items[indexPath.item] + } + set(item) { + var section = self._sectionModels[indexPath.section] + section.items[indexPath.item] = item + self._sectionModels[indexPath.section] = section + } } - public func modelAtIndexPath(_ indexPath: IndexPath) throws -> Any { - return itemAtIndexPath(indexPath) + public func model(_ indexPath: IndexPath) throws -> Any { + return self[indexPath] } public func setSections(_ sections: [S]) { @@ -188,7 +195,7 @@ public class CollectionViewSectionedDataSource override func _rx_collectionView(_ collectionView: UICollectionView, cellForItemAtIndexPath indexPath: IndexPath) -> UICollectionViewCell { precondition(indexPath.item < _sectionModels[indexPath.section].items.count) - return configureCell(self, collectionView, indexPath, itemAtIndexPath(indexPath)) + return configureCell(self, collectionView, indexPath, self[indexPath]) } override func _rx_collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: IndexPath) -> UICollectionReusableView { diff --git a/RxExample/RxDataSources/DataSources/TableViewSectionedDataSource.swift b/RxExample/RxDataSources/DataSources/TableViewSectionedDataSource.swift index c454b584..1d0ebb2b 100644 --- a/RxExample/RxDataSources/DataSources/TableViewSectionedDataSource.swift +++ b/RxExample/RxDataSources/DataSources/TableViewSectionedDataSource.swift @@ -139,18 +139,19 @@ public class RxTableViewSectionedDataSource return Section(original: sectionModel.model, items: sectionModel.items) } - public func itemAtIndexPath(_ indexPath: IndexPath) -> I { - return self._sectionModels[indexPath.section].items[indexPath.item] + public subscript(indexPath: IndexPath) -> I { + get { + return self._sectionModels[indexPath.section].items[indexPath.item] + } + set(item) { + var section = self._sectionModels[indexPath.section] + section.items[indexPath.item] = item + self._sectionModels[indexPath.section] = section + } } - public func setItem(item: I, indexPath: IndexPath) { - var section = self._sectionModels[indexPath.section] - section.items[indexPath.item] = item - self._sectionModels[indexPath.section] = section - } - - public func modelAtIndexPath(_ indexPath: IndexPath) throws -> Any { - return itemAtIndexPath(indexPath) + public func model(_ indexPath: IndexPath) throws -> Any { + return self[indexPath] } public func setSections(_ sections: [S]) { @@ -238,7 +239,7 @@ public class RxTableViewSectionedDataSource override func _rx_tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath) -> UITableViewCell { precondition(indexPath.item < _sectionModels[indexPath.section].items.count) - return configureCell(self, tableView, indexPath, itemAtIndexPath(indexPath)) + return configureCell(self, tableView, indexPath, self[indexPath]) } override func _rx_tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { diff --git a/RxExample/RxExample/Examples/SimpleTableViewExampleSectioned/SimpleTableViewExampleSectionedViewController.swift b/RxExample/RxExample/Examples/SimpleTableViewExampleSectioned/SimpleTableViewExampleSectionedViewController.swift index 5e8338a3..5af89c9b 100644 --- a/RxExample/RxExample/Examples/SimpleTableViewExampleSectioned/SimpleTableViewExampleSectionedViewController.swift +++ b/RxExample/RxExample/Examples/SimpleTableViewExampleSectioned/SimpleTableViewExampleSectionedViewController.swift @@ -56,7 +56,7 @@ class SimpleTableViewExampleSectionedViewController tableView.rx .itemSelected .map { indexPath in - return (indexPath, dataSource.itemAtIndexPath(indexPath)) + return (indexPath, dataSource[indexPath]) } .subscribe(onNext: { indexPath, model in DefaultWireframe.presentAlert("Tapped `\(model)` @ \(indexPath)") diff --git a/RxExample/RxExample/Examples/TableViewPartialUpdates/PartialUpdatesViewController.swift b/RxExample/RxExample/Examples/TableViewPartialUpdates/PartialUpdatesViewController.swift index a5e63179..dc4b7e8d 100644 --- a/RxExample/RxExample/Examples/TableViewPartialUpdates/PartialUpdatesViewController.swift +++ b/RxExample/RxExample/Examples/TableViewPartialUpdates/PartialUpdatesViewController.swift @@ -164,7 +164,7 @@ class PartialUpdatesViewController : ViewController { dataSource.supplementaryViewFactory = { (dataSource, cv, kind, ip) in let section = cv.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "Section", for: ip) as! NumberSectionView - section.value!.text = "\(dataSource.sectionAtIndex(ip.section).model)" + section.value!.text = "\(dataSource[ip.section].model)" return section } diff --git a/Tests/RxCocoaTests/TestImplementations/SectionedViewDataSourceMock.swift b/Tests/RxCocoaTests/TestImplementations/SectionedViewDataSourceMock.swift index 96a7c47b..92ff4d80 100644 --- a/Tests/RxCocoaTests/TestImplementations/SectionedViewDataSourceMock.swift +++ b/Tests/RxCocoaTests/TestImplementations/SectionedViewDataSourceMock.swift @@ -27,7 +27,7 @@ import UIKit super.init() } - func modelAtIndexPath(_ indexPath: IndexPath) throws -> Any { + func model(_ indexPath: IndexPath) throws -> Any { return items![indexPath.item] } diff --git a/Tests/RxCocoaTests/UICollectionView+RxTests.swift b/Tests/RxCocoaTests/UICollectionView+RxTests.swift index e65c5ae8..09f2f444 100644 --- a/Tests/RxCocoaTests/UICollectionView+RxTests.swift +++ b/Tests/RxCocoaTests/UICollectionView+RxTests.swift @@ -248,7 +248,7 @@ class UICollectionViewTests : RxTest { } let (collectionView, dataSourceSubscription) = createView() - let model: Int = try! collectionView.rx.modelAtIndexPath(IndexPath(item: 1, section: 0)) + let model: Int = try! collectionView.rx.model(IndexPath(item: 1, section: 0)) XCTAssertEqual(model, 2) diff --git a/Tests/RxCocoaTests/UITableView+RxTests.swift b/Tests/RxCocoaTests/UITableView+RxTests.swift index 701c1d84..51624d58 100644 --- a/Tests/RxCocoaTests/UITableView+RxTests.swift +++ b/Tests/RxCocoaTests/UITableView+RxTests.swift @@ -352,7 +352,7 @@ class UITableViewTests : RxTest { let (tableView, dataSourceSubscription) = createView() - let model: Int = try! tableView.rx.modelAtIndexPath(IndexPath(item: 1, section: 0)) + let model: Int = try! tableView.rx.model(IndexPath(item: 1, section: 0)) XCTAssertEqual(model, 2)