From 3127ef4c042df33f48355dee728ef16af78545c6 Mon Sep 17 00:00:00 2001 From: sergdort Date: Fri, 14 Jul 2017 11:13:03 +0100 Subject: [PATCH] Add `modelSelected` to the UIPickerView extension --- RxCocoa/iOS/UIPickerView+Rx.swift | 44 +++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/RxCocoa/iOS/UIPickerView+Rx.swift b/RxCocoa/iOS/UIPickerView+Rx.swift index c4405db2a..69dc2eee7 100644 --- a/RxCocoa/iOS/UIPickerView+Rx.swift +++ b/RxCocoa/iOS/UIPickerView+Rx.swift @@ -53,6 +53,18 @@ return RxPickerViewDelegateProxy.installForwardDelegate(delegate, retainDelegate: false, onProxyForObject: self.base) } + /** + Reactive wrapper for `dataSource`. + + For more information take a look at `DelegateProxyType` protocol documentation. + */ + public var dataSource: DelegateProxy { + return RxPickerViewDataSourceProxy.proxyForObject(base) + } + + /** + Reactive wrapper for `delegate` message `pickerView:didSelectRow:inComponent:`. + */ public var itemSelected: ControlEvent<(Int, Int)> { let source = delegate .methodInvoked(#selector(UIPickerViewDelegate.pickerView(_:didSelectRow:inComponent:))) @@ -62,6 +74,29 @@ return ControlEvent(events: source) } + /** + Reactive wrapper for `delegate` message `pickerView:didSelectRow:inComponent:`. + + It can be only used when one of the `rx.itemTitles, rx.itemAttributedTitles, items(_ source: O)` methods is used to bind observable sequence, + or any other data source conforming to a `ViewDataSourceType` protocol. + + ``` + pickerView.rx.modelSelected(MyModel.self) + .map { ... + ``` + - parameter modelType: Type of a Model which bound to the dataSource + */ + public func modelSelected(_ modelType: T.Type) -> ControlEvent { + let source = itemSelected.flatMap { [weak view = self.base as UIPickerView] (row, _) -> Observable in + guard let view = view else { + return Observable.empty() + } + return Observable.just(try view.rx.model(at: row)) + } + + return ControlEvent(events: source) + } + /** Binds sequences of elements to picker view rows. @@ -191,6 +226,15 @@ return Disposables.create(delegateSubscription, dataSourceSubscription) } } + + /** + Synchronous helper method for retrieving a model at indexPath through a reactive data source. + */ + public func model(at index: Int) throws -> T { + let dataSource: ViewDataSourceType = castOrFatalError(self.dataSource.forwardToDelegate(), message: "This method only works in case one of the `rx.itemTitles, rx.itemAttributedTitles, items(_ source: O)` methods was used.") + + return castOrFatalError(try dataSource.model(at: index)) + } } #endif