@@ -111,22 +111,31 @@ extension Reactive where Base: UITableView {
111111 -> ( _ source: Source )
112112 -> Disposable
113113 where DataSource. Element == Source . Element {
114- return { source in
115- // This is called for side effects only, and to make sure delegate proxy is in place when
116- // data source is being bound.
117- // This is needed because theoretically the data source subscription itself might
118- // call `self.rx.delegate`. If that happens, it might cause weird side effects since
119- // setting data source will set delegate, and UITableView might get into a weird state.
120- // Therefore it's better to set delegate proxy first, just to be sure.
121- _ = self . delegate
122- // Strong reference is needed because data source is in use until result subscription is disposed
123- return source. subscribeProxyDataSource ( ofObject: self . base, dataSource: dataSource as UITableViewDataSource , retainDataSource: true ) { [ weak tableView = self . base] ( _: RxTableViewDataSourceProxy , event) -> Void in
124- guard let tableView = tableView else {
125- return
126- }
127- dataSource. tableView ( tableView, observedEvent: event)
128- }
129- }
114+ if base. isDiffableDataSource ( ) {
115+ return { source in
116+ _ = self . delegate
117+ return source. subscribe { [ weak tableView = self . base] event -> Void in
118+ guard let tableView = tableView else { return }
119+ dataSource. tableView ( tableView, observedEvent: event)
120+ }
121+ }
122+ }
123+ return { source in
124+ // This is called for side effects only, and to make sure delegate proxy is in place when
125+ // data source is being bound.
126+ // This is needed because theoretically the data source subscription itself might
127+ // call `self.rx.delegate`. If that happens, it might cause weird side effects since
128+ // setting data source will set delegate, and UITableView might get into a weird state.
129+ // Therefore it's better to set delegate proxy first, just to be sure.
130+ _ = self . delegate
131+ // Strong reference is needed because data source is in use until result subscription is disposed
132+ return source. subscribeProxyDataSource ( ofObject: self . base, dataSource: dataSource as UITableViewDataSource , retainDataSource: true ) { [ weak tableView = self . base] ( _: RxTableViewDataSourceProxy , event) -> Void in
133+ guard let tableView = tableView else {
134+ return
135+ }
136+ dataSource. tableView ( tableView, observedEvent: event)
137+ }
138+ }
130139 }
131140
132141}
@@ -138,8 +147,31 @@ extension Reactive where Base: UITableView {
138147 For more information take a look at `DelegateProxyType` protocol documentation.
139148 */
140149 public var dataSource : DelegateProxy < UITableView , UITableViewDataSource > {
141- RxTableViewDataSourceProxy . proxy ( for: base)
150+ fatalErrorIfDiffableDataSource ( )
151+ return RxTableViewDataSourceProxy . proxy ( for: base)
142152 }
153+
154+ private func fatalErrorIfDiffableDataSource( _ message: @autoclosure ( ) -> String = String ( ) , file: StaticString = #file, line: UInt = #line) {
155+ if base. isDiffableDataSource ( ) {
156+ fatalError ( message ( ) , file: file, line: line)
157+ }
158+ }
159+
160+ private var commitEditingStyleMethodInvoked : Observable < [ Any ] > {
161+ dataSourceMethodInvoked ( for: #selector( UITableViewDataSource . tableView ( _: commit: forRowAt: ) ) )
162+ }
163+
164+ private var moveRowAtMethodInvoked : Observable < [ Any ] > {
165+ dataSourceMethodInvoked ( for: #selector( UITableViewDataSource . tableView ( _: moveRowAt: to: ) ) )
166+ }
167+
168+ private func dataSourceMethodInvoked( for selector: Selector ) -> Observable < [ Any ] > {
169+ if self . base. isDiffableDataSource ( ) {
170+ return ( self . base. dataSource as! NSObject ) . rx. methodInvoked ( selector)
171+ } else {
172+ return self . dataSource. methodInvoked ( selector)
173+ }
174+ }
143175
144176 /**
145177 Installs data source as forwarding delegate on `rx.dataSource`.
@@ -221,22 +253,21 @@ extension Reactive where Base: UITableView {
221253 Reactive wrapper for `delegate` message `tableView:commitEditingStyle:forRowAtIndexPath:`.
222254 */
223255 public var itemInserted : ControlEvent < IndexPath > {
224- let source = self . dataSource. methodInvoked ( #selector( UITableViewDataSource . tableView ( _: commit: forRowAt: ) ) )
225- . filter { a in
226- return UITableViewCell . EditingStyle ( rawValue: ( try castOrThrow ( NSNumber . self, a [ 1 ] ) ) . intValue) == . insert
227- }
228- . map { a in
229- return ( try castOrThrow ( IndexPath . self, a [ 2 ] ) )
230- }
256+ let indexSource = commitEditingStyleMethodInvoked
257+ . filter { a in
258+ return UITableViewCell . EditingStyle ( rawValue: ( try castOrThrow ( NSNumber . self, a [ 1 ] ) ) . intValue) == . insert
259+ } . map { a in
260+ return ( try castOrThrow ( IndexPath . self, a [ 2 ] ) )
261+ }
231262
232- return ControlEvent ( events: source )
263+ return ControlEvent ( events: indexSource )
233264 }
234265
235266 /**
236267 Reactive wrapper for `delegate` message `tableView:commitEditingStyle:forRowAtIndexPath:`.
237268 */
238269 public var itemDeleted : ControlEvent < IndexPath > {
239- let source = self . dataSource . methodInvoked ( #selector ( UITableViewDataSource . tableView ( _ : commit : forRowAt : ) ) )
270+ let source = commitEditingStyleMethodInvoked
240271 . filter { a in
241272 return UITableViewCell . EditingStyle ( rawValue: ( try castOrThrow ( NSNumber . self, a [ 1 ] ) ) . intValue) == . delete
242273 }
@@ -251,7 +282,7 @@ extension Reactive where Base: UITableView {
251282 Reactive wrapper for `delegate` message `tableView:moveRowAtIndexPath:toIndexPath:`.
252283 */
253284 public var itemMoved : ControlEvent < ItemMovedEvent > {
254- let source : Observable < ItemMovedEvent > = self . dataSource . methodInvoked ( #selector ( UITableViewDataSource . tableView ( _ : moveRowAt : to : ) ) )
285+ let source : Observable < ItemMovedEvent > = moveRowAtMethodInvoked
255286 . map { a in
256287 return ( try castOrThrow ( IndexPath . self, a [ 1 ] ) , try castOrThrow ( IndexPath . self, a [ 2 ] ) )
257288 }
@@ -356,9 +387,18 @@ extension Reactive where Base: UITableView {
356387 Synchronous helper method for retrieving a model at indexPath through a reactive data source.
357388 */
358389 public func model< T> ( at indexPath: IndexPath ) throws -> T {
359- let dataSource : SectionedViewDataSourceType = castOrFatalError ( self . dataSource. forwardToDelegate ( ) , message: " This method only works in case one of the `rx.items*` methods was used. " )
360-
361- let element = try dataSource. model ( at: indexPath)
390+ let element : Any
391+
392+ if let dataSource = base. diffableDataSource ( ) {
393+ guard let item = dataSource. model ( for: indexPath) else {
394+ throw RxCocoaError . itemsNotYetBound ( object: dataSource)
395+ }
396+ element = item
397+ } else {
398+ let dataSource : SectionedViewDataSourceType = castOrFatalError ( self . dataSource. forwardToDelegate ( ) , message: " This method only works in case one of the `rx.items*` methods was used. " )
399+
400+ element = try dataSource. model ( at: indexPath)
401+ }
362402
363403 return castOrFatalError ( element)
364404 }
0 commit comments