@@ -111,22 +111,31 @@ extension Reactive where Base: UITableView {
111
111
-> ( _ source: Source )
112
112
-> Disposable
113
113
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
+ }
130
139
}
131
140
132
141
}
@@ -138,8 +147,31 @@ extension Reactive where Base: UITableView {
138
147
For more information take a look at `DelegateProxyType` protocol documentation.
139
148
*/
140
149
public var dataSource : DelegateProxy < UITableView , UITableViewDataSource > {
141
- RxTableViewDataSourceProxy . proxy ( for: base)
150
+ fatalErrorIfDiffableDataSource ( )
151
+ return RxTableViewDataSourceProxy . proxy ( for: base)
142
152
}
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
+ }
143
175
144
176
/**
145
177
Installs data source as forwarding delegate on `rx.dataSource`.
@@ -221,22 +253,21 @@ extension Reactive where Base: UITableView {
221
253
Reactive wrapper for `delegate` message `tableView:commitEditingStyle:forRowAtIndexPath:`.
222
254
*/
223
255
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
+ }
231
262
232
- return ControlEvent ( events: source )
263
+ return ControlEvent ( events: indexSource )
233
264
}
234
265
235
266
/**
236
267
Reactive wrapper for `delegate` message `tableView:commitEditingStyle:forRowAtIndexPath:`.
237
268
*/
238
269
public var itemDeleted : ControlEvent < IndexPath > {
239
- let source = self . dataSource . methodInvoked ( #selector ( UITableViewDataSource . tableView ( _ : commit : forRowAt : ) ) )
270
+ let source = commitEditingStyleMethodInvoked
240
271
. filter { a in
241
272
return UITableViewCell . EditingStyle ( rawValue: ( try castOrThrow ( NSNumber . self, a [ 1 ] ) ) . intValue) == . delete
242
273
}
@@ -251,7 +282,7 @@ extension Reactive where Base: UITableView {
251
282
Reactive wrapper for `delegate` message `tableView:moveRowAtIndexPath:toIndexPath:`.
252
283
*/
253
284
public var itemMoved : ControlEvent < ItemMovedEvent > {
254
- let source : Observable < ItemMovedEvent > = self . dataSource . methodInvoked ( #selector ( UITableViewDataSource . tableView ( _ : moveRowAt : to : ) ) )
285
+ let source : Observable < ItemMovedEvent > = moveRowAtMethodInvoked
255
286
. map { a in
256
287
return ( try castOrThrow ( IndexPath . self, a [ 1 ] ) , try castOrThrow ( IndexPath . self, a [ 2 ] ) )
257
288
}
@@ -356,9 +387,18 @@ extension Reactive where Base: UITableView {
356
387
Synchronous helper method for retrieving a model at indexPath through a reactive data source.
357
388
*/
358
389
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
+ }
362
402
363
403
return castOrFatalError ( element)
364
404
}
0 commit comments