mirror of
https://github.com/ReactiveX/RxSwift.git
synced 2024-10-04 05:57:23 +03:00
Add prefetchDataSource
support for UITableView
This commit is contained in:
parent
bc3bb79df4
commit
e51fbf901f
@ -136,6 +136,10 @@
|
||||
B5624790203515DE00D3EE75 /* RxCollectionViewDataSourcePrefetchingProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B562478D2035154900D3EE75 /* RxCollectionViewDataSourcePrefetchingProxy.swift */; };
|
||||
B5624791203515DF00D3EE75 /* RxCollectionViewDataSourcePrefetchingProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B562478D2035154900D3EE75 /* RxCollectionViewDataSourcePrefetchingProxy.swift */; };
|
||||
B5624792203515DF00D3EE75 /* RxCollectionViewDataSourcePrefetchingProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B562478D2035154900D3EE75 /* RxCollectionViewDataSourcePrefetchingProxy.swift */; };
|
||||
B5624794203532F500D3EE75 /* RxTableViewDataSourcePrefetchingProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5624793203532F500D3EE75 /* RxTableViewDataSourcePrefetchingProxy.swift */; };
|
||||
B5624795203532F500D3EE75 /* RxTableViewDataSourcePrefetchingProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5624793203532F500D3EE75 /* RxTableViewDataSourcePrefetchingProxy.swift */; };
|
||||
B5624796203532F500D3EE75 /* RxTableViewDataSourcePrefetchingProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5624793203532F500D3EE75 /* RxTableViewDataSourcePrefetchingProxy.swift */; };
|
||||
B5624797203532F500D3EE75 /* RxTableViewDataSourcePrefetchingProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5624793203532F500D3EE75 /* RxTableViewDataSourcePrefetchingProxy.swift */; };
|
||||
C801DE361F6EAD3C008DB060 /* SingleTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C801DE351F6EAD3C008DB060 /* SingleTest.swift */; };
|
||||
C801DE371F6EAD3C008DB060 /* SingleTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C801DE351F6EAD3C008DB060 /* SingleTest.swift */; };
|
||||
C801DE381F6EAD3C008DB060 /* SingleTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C801DE351F6EAD3C008DB060 /* SingleTest.swift */; };
|
||||
@ -1802,6 +1806,7 @@
|
||||
A5CD03891F1660F40005A376 /* RxPickerViewAdapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxPickerViewAdapter.swift; sourceTree = "<group>"; };
|
||||
AAE623751C82475700FC7801 /* UIProgressView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIProgressView+Rx.swift"; sourceTree = "<group>"; };
|
||||
B562478D2035154900D3EE75 /* RxCollectionViewDataSourcePrefetchingProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RxCollectionViewDataSourcePrefetchingProxy.swift; sourceTree = "<group>"; };
|
||||
B5624793203532F500D3EE75 /* RxTableViewDataSourcePrefetchingProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RxTableViewDataSourcePrefetchingProxy.swift; sourceTree = "<group>"; };
|
||||
C801DE351F6EAD3C008DB060 /* SingleTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleTest.swift; sourceTree = "<group>"; };
|
||||
C801DE391F6EAD48008DB060 /* MaybeTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MaybeTest.swift; sourceTree = "<group>"; };
|
||||
C801DE3D1F6EAD57008DB060 /* CompletableTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompletableTest.swift; sourceTree = "<group>"; };
|
||||
@ -3095,12 +3100,14 @@
|
||||
C88253F91B8A752B00B02D69 /* Proxies */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B562478D2035154900D3EE75 /* RxCollectionViewDataSourcePrefetchingProxy.swift */,
|
||||
C88253FC1B8A752B00B02D69 /* RxCollectionViewDataSourceProxy.swift */,
|
||||
C88253FD1B8A752B00B02D69 /* RxCollectionViewDelegateProxy.swift */,
|
||||
C88253FE1B8A752B00B02D69 /* RxScrollViewDelegateProxy.swift */,
|
||||
C88253FF1B8A752B00B02D69 /* RxSearchBarDelegateProxy.swift */,
|
||||
ECBBA59D1DF8C0D400DDDC2E /* RxTabBarControllerDelegateProxy.swift */,
|
||||
88D98F2D1CE7549A00D50457 /* RxTabBarDelegateProxy.swift */,
|
||||
B5624793203532F500D3EE75 /* RxTableViewDataSourcePrefetchingProxy.swift */,
|
||||
C88254001B8A752B00B02D69 /* RxTableViewDataSourceProxy.swift */,
|
||||
C88254011B8A752B00B02D69 /* RxTableViewDelegateProxy.swift */,
|
||||
C88254021B8A752B00B02D69 /* RxTextViewDelegateProxy.swift */,
|
||||
@ -3110,7 +3117,6 @@
|
||||
D9080ACD1EA05A16002B433B /* RxNavigationControllerDelegateProxy.swift */,
|
||||
4613457B1D9A4AEE001ABAF2 /* RxWebViewDelegateProxy.swift */,
|
||||
A520FFFB1F0D291500573734 /* RxPickerViewDataSourceProxy.swift */,
|
||||
B562478D2035154900D3EE75 /* RxCollectionViewDataSourcePrefetchingProxy.swift */,
|
||||
);
|
||||
path = Proxies;
|
||||
sourceTree = "<group>";
|
||||
@ -4228,6 +4234,7 @@
|
||||
C88254181B8A752B00B02D69 /* ItemEvents.swift in Sources */,
|
||||
C89AB1731DAAC1680065FBE6 /* ControlTarget.swift in Sources */,
|
||||
C882541B1B8A752B00B02D69 /* RxTableViewDataSourceType.swift in Sources */,
|
||||
B5624794203532F500D3EE75 /* RxTableViewDataSourcePrefetchingProxy.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -4252,6 +4259,7 @@
|
||||
C88F76821CE5341700D5A014 /* TextInput.swift in Sources */,
|
||||
C8C8BCD01F8944B800501D4D /* BehaviorRelay.swift in Sources */,
|
||||
C8091C581FAA39C1001DB32A /* ControlEvent+Signal.swift in Sources */,
|
||||
B5624795203532F500D3EE75 /* RxTableViewDataSourcePrefetchingProxy.swift in Sources */,
|
||||
C89AB1DF1DAAC3350065FBE6 /* ObservableConvertibleType+Driver.swift in Sources */,
|
||||
6B9CA56C202A1F44002C2D11 /* KeyPathBinder.swift in Sources */,
|
||||
C89AB1D71DAAC3350065FBE6 /* Driver+Subscription.swift in Sources */,
|
||||
@ -5458,6 +5466,7 @@
|
||||
C89AB2111DAAC3350065FBE6 /* Logging.swift in Sources */,
|
||||
C89AB1761DAAC1680065FBE6 /* ControlTarget.swift in Sources */,
|
||||
D9080AD61EA05DEC002B433B /* UINavigationController+Rx.swift in Sources */,
|
||||
B5624797203532F500D3EE75 /* RxTableViewDataSourcePrefetchingProxy.swift in Sources */,
|
||||
C8E65EFE1F6E91D1004478C3 /* Binder.swift in Sources */,
|
||||
C89AB21D1DAAC3350065FBE6 /* NSObject+Rx+RawRepresentable.swift in Sources */,
|
||||
6B9CA56A202A1F44002C2D11 /* KeyPathBinder.swift in Sources */,
|
||||
@ -5553,6 +5562,7 @@
|
||||
C89AB20C1DAAC3350065FBE6 /* KVORepresentable.swift in Sources */,
|
||||
54D213921CE08D0C0028D5B4 /* UINavigationItem+Rx.swift in Sources */,
|
||||
C89AB1F41DAAC3350065FBE6 /* SharedSequence+Operators.swift in Sources */,
|
||||
B5624796203532F500D3EE75 /* RxTableViewDataSourcePrefetchingProxy.swift in Sources */,
|
||||
C817729A1E7F408100EA679B /* Deprecated.swift in Sources */,
|
||||
C8BCD3EF1C14B5FB005F1280 /* UIView+Rx.swift in Sources */,
|
||||
46307D4F1CDE77D800E47A1C /* UIAlertAction+Rx.swift in Sources */,
|
||||
|
@ -0,0 +1,88 @@
|
||||
//
|
||||
// RxTableViewDataSourcePrefetchingProxy.swift
|
||||
// RxCocoa
|
||||
//
|
||||
// Created by Rowan Livingstone on 2/15/18.
|
||||
// Copyright © 2018 Krunoslav Zaher. All rights reserved.
|
||||
//
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
|
||||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
@available(iOS 10.0, tvOS 10.0, *)
|
||||
extension UITableView: HasPrefetchDataSource {
|
||||
public typealias PrefetchDataSource = UITableViewDataSourcePrefetching
|
||||
}
|
||||
|
||||
@available(iOS 10.0, tvOS 10.0, *)
|
||||
let tableViewPrefetchDataSourceNotSet = TableViewPrefetchDataSourceNotSet()
|
||||
|
||||
@available(iOS 10.0, tvOS 10.0, *)
|
||||
final class TableViewPrefetchDataSourceNotSet : NSObject, UITableViewDataSourcePrefetching {
|
||||
|
||||
func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {}
|
||||
|
||||
}
|
||||
|
||||
@available(iOS 10.0, tvOS 10.0, *)
|
||||
open class RxTableViewDataSourcePrefetchingProxy: DelegateProxy<UITableView, UITableViewDataSourcePrefetching>, DelegateProxyType, UITableViewDataSourcePrefetching {
|
||||
|
||||
/// Typed parent object.
|
||||
public weak private(set) var tableView: UITableView?
|
||||
|
||||
/// - parameter tableView: Parent object for delegate proxy.
|
||||
public init(tableView: ParentObject) {
|
||||
self.tableView = tableView
|
||||
super.init(parentObject: tableView, delegateProxy: RxTableViewDataSourcePrefetchingProxy.self)
|
||||
}
|
||||
|
||||
// Register known implementations
|
||||
public static func registerKnownImplementations() {
|
||||
self.register { RxTableViewDataSourcePrefetchingProxy(tableView: $0) }
|
||||
}
|
||||
|
||||
fileprivate var _prefetchItemsPublishSubject: PublishSubject<[IndexPath]>?
|
||||
|
||||
/// Optimized version used for observing prefetch items callbacks.
|
||||
internal var prefetchItemsPublishSubject: PublishSubject<[IndexPath]> {
|
||||
if let subject = _prefetchItemsPublishSubject {
|
||||
return subject
|
||||
}
|
||||
|
||||
let subject = PublishSubject<[IndexPath]>()
|
||||
_prefetchItemsPublishSubject = subject
|
||||
|
||||
return subject
|
||||
}
|
||||
|
||||
private weak var _requiredMethodsPrefetchDataSource: UITableViewDataSourcePrefetching? = tableViewPrefetchDataSourceNotSet
|
||||
|
||||
// MARK: delegate
|
||||
|
||||
/// Required delegate method implementation.
|
||||
public func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
|
||||
if let subject = _prefetchItemsPublishSubject {
|
||||
subject.on(.next(indexPaths))
|
||||
}
|
||||
|
||||
(_requiredMethodsPrefetchDataSource ?? tableViewPrefetchDataSourceNotSet).tableView(tableView, prefetchRowsAt: indexPaths)
|
||||
}
|
||||
|
||||
/// For more information take a look at `DelegateProxyType`.
|
||||
open override func setForwardToDelegate(_ forwardToDelegate: UITableViewDataSourcePrefetching?, retainDelegate: Bool) {
|
||||
_requiredMethodsPrefetchDataSource = forwardToDelegate ?? tableViewPrefetchDataSourceNotSet
|
||||
super.setForwardToDelegate(forwardToDelegate, retainDelegate: retainDelegate)
|
||||
}
|
||||
|
||||
deinit {
|
||||
if let subject = _prefetchItemsPublishSubject {
|
||||
subject.on(.completed)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -372,6 +372,47 @@ extension Reactive where Base: UITableView {
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 10.0, tvOS 10.0, *)
|
||||
extension Reactive where Base: UITableView {
|
||||
|
||||
/// Reactive wrapper for `prefetchDataSource`.
|
||||
///
|
||||
/// For more information take a look at `DelegateProxyType` protocol documentation.
|
||||
public var prefetchDataSource: DelegateProxy<UITableView, UITableViewDataSourcePrefetching> {
|
||||
return RxTableViewDataSourcePrefetchingProxy.proxy(for: base)
|
||||
}
|
||||
|
||||
/**
|
||||
Installs prefetch data source as forwarding delegate on `rx.prefetchDataSource`.
|
||||
Prefetch data source won't be retained.
|
||||
|
||||
It enables using normal delegate mechanism with reactive delegate mechanism.
|
||||
|
||||
- parameter prefetchDataSource: Prefetch data source object.
|
||||
- returns: Disposable object that can be used to unbind the data source.
|
||||
*/
|
||||
public func setPrefetchDataSource(_ prefetchDataSource: UITableViewDataSourcePrefetching)
|
||||
-> Disposable {
|
||||
return RxTableViewDataSourcePrefetchingProxy.installForwardDelegate(prefetchDataSource, retainDelegate: false, onProxyForObject: self.base)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `prefetchDataSource` message `tableView(_:prefetchRowsAt:)`.
|
||||
public var prefetchItems: ControlEvent<[IndexPath]> {
|
||||
let source = RxTableViewDataSourcePrefetchingProxy.proxy(for: base).prefetchItemsPublishSubject
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
/// Reactive wrapper for `prefetchDataSource` message `tableView(_:cancelPrefetchingForRowsAt:)`.
|
||||
public var cancelPrefetchingForItems: ControlEvent<[IndexPath]> {
|
||||
let source = prefetchDataSource.methodInvoked(#selector(UITableViewDataSourcePrefetching.tableView(_:cancelPrefetchingForRowsAt:)))
|
||||
.map { a in
|
||||
return try castOrThrow(Array<IndexPath>.self, a[1])
|
||||
}
|
||||
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#if os(tvOS)
|
||||
|
@ -218,6 +218,42 @@ final class UITableViewTests : RxTest {
|
||||
dataSourceSubscription.dispose()
|
||||
}
|
||||
|
||||
@available(iOS 10.0, tvOS 10.0, *)
|
||||
func test_prefetchItems() {
|
||||
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
||||
|
||||
var indexPaths: [IndexPath] = []
|
||||
|
||||
let subscription = tableView.rx.prefetchItems
|
||||
.subscribe(onNext: {
|
||||
indexPaths = $0
|
||||
})
|
||||
|
||||
let testIndexPaths = [IndexPath(item: 1, section: 0), IndexPath(item: 2, section: 0)]
|
||||
tableView.prefetchDataSource!.tableView(tableView, prefetchRowsAt: testIndexPaths)
|
||||
|
||||
XCTAssertEqual(indexPaths, testIndexPaths)
|
||||
subscription.dispose()
|
||||
}
|
||||
|
||||
@available(iOS 10.0, tvOS 10.0, *)
|
||||
func test_cancelPrefetchingForItems() {
|
||||
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
||||
|
||||
var indexPaths: [IndexPath] = []
|
||||
|
||||
let subscription = tableView.rx.cancelPrefetchingForItems
|
||||
.subscribe(onNext: {
|
||||
indexPaths = $0
|
||||
})
|
||||
|
||||
let testIndexPaths = [IndexPath(item: 1, section: 0), IndexPath(item: 2, section: 0)]
|
||||
tableView.prefetchDataSource!.tableView!(tableView, cancelPrefetchingForRowsAt: testIndexPaths)
|
||||
|
||||
XCTAssertEqual(indexPaths, testIndexPaths)
|
||||
subscription.dispose()
|
||||
}
|
||||
|
||||
func test_delegateEventCompletesOnDealloc1() {
|
||||
let items: Observable<[Int]> = Observable.just([1, 2, 3])
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user