123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- //
- // RxPickerViewAdapter.swift
- // RxDataSources
- //
- // Created by Sergey Shulga on 04/07/2017.
- // Copyright © 2017 kzaher. All rights reserved.
- //
- #if os(iOS)
- import Foundation
- import UIKit
- #if !RX_NO_MODULE
- import RxSwift
- import RxCocoa
- #endif
- /// A reactive UIPickerView adapter which uses `func pickerView(UIPickerView, titleForRow: Int, forComponent: Int)` to display the content
- /**
- Example:
-
- let adapter = RxPickerViewStringAdapter<[T]>(...)
-
- items
- .bind(to: firstPickerView.rx.items(adapter: adapter))
- .disposed(by: disposeBag)
-
- */
- open class RxPickerViewStringAdapter<Components>: RxPickerViewDataSource<Components>, UIPickerViewDelegate {
- /**
- - parameter dataSource
- - parameter pickerView
- - parameter components
- - parameter row
- - parameter component
- */
- public typealias TitleForRow = (
- _ dataSource: RxPickerViewStringAdapter<Components>,
- _ pickerView: UIPickerView,
- _ components: Components,
- _ row: Int,
- _ component: Int
- ) -> String?
-
- private let titleForRow: TitleForRow
- /**
- - parameter components: Initial content value.
- - parameter numberOfComponents: Implementation of corresponding delegate method.
- - parameter numberOfRowsInComponent: Implementation of corresponding delegate method.
- - parameter titleForRow: Implementation of corresponding adapter method that converts component to `String`.
- */
- public init(components: Components,
- numberOfComponents: @escaping NumberOfComponents,
- numberOfRowsInComponent: @escaping NumberOfRowsInComponent,
- titleForRow: @escaping TitleForRow) {
- self.titleForRow = titleForRow
- super.init(components: components,
- numberOfComponents: numberOfComponents,
- numberOfRowsInComponent: numberOfRowsInComponent)
- }
-
- open func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
- return titleForRow(self, pickerView, components, row, component)
- }
- }
- /// A reactive UIPickerView adapter which uses `func pickerView(UIPickerView, viewForRow: Int, forComponent: Int, reusing: UIView?)` to display the content
- /**
- Example:
-
- let adapter = RxPickerViewAttributedStringAdapter<[T]>(...)
-
- items
- .bind(to: firstPickerView.rx.items(adapter: adapter))
- .disposed(by: disposeBag)
-
- */
- open class RxPickerViewAttributedStringAdapter<Components>: RxPickerViewDataSource<Components>, UIPickerViewDelegate {
- /**
- - parameter dataSource
- - parameter pickerView
- - parameter components
- - parameter row
- - parameter component
- */
- public typealias AttributedTitleForRow = (
- _ dataSource: RxPickerViewAttributedStringAdapter<Components>,
- _ pickerView: UIPickerView,
- _ components: Components,
- _ row: Int,
- _ component: Int
- ) -> NSAttributedString?
-
- private let attributedTitleForRow: AttributedTitleForRow
- /**
- - parameter components: Initial content value.
- - parameter numberOfComponents: Implementation of corresponding delegate method.
- - parameter numberOfRowsInComponent: Implementation of corresponding delegate method.
- - parameter attributedTitleForRow: Implementation of corresponding adapter method that converts component to `NSAttributedString`.
- */
- public init(components: Components,
- numberOfComponents: @escaping NumberOfComponents,
- numberOfRowsInComponent: @escaping NumberOfRowsInComponent,
- attributedTitleForRow: @escaping AttributedTitleForRow) {
- self.attributedTitleForRow = attributedTitleForRow
- super.init(components: components,
- numberOfComponents: numberOfComponents,
- numberOfRowsInComponent: numberOfRowsInComponent)
- }
-
- open func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
- return attributedTitleForRow(self, pickerView, components, row, component)
- }
- }
- /// A reactive UIPickerView adapter which uses `func pickerView(pickerView:, viewForRow row:, forComponent component:)` to display the content
- /**
- Example:
-
- let adapter = RxPickerViewViewAdapter<[T]>(...)
-
- items
- .bind(to: firstPickerView.rx.items(adapter: adapter))
- .disposed(by: disposeBag)
-
- */
- open class RxPickerViewViewAdapter<Components>: RxPickerViewDataSource<Components>, UIPickerViewDelegate {
- /**
- - parameter dataSource
- - parameter pickerView
- - parameter components
- - parameter row
- - parameter component
- - parameter view
- */
- public typealias ViewForRow = (
- _ dataSource: RxPickerViewViewAdapter<Components>,
- _ pickerView: UIPickerView,
- _ components: Components,
- _ row: Int,
- _ component: Int,
- _ view: UIView?
- ) -> UIView
-
- private let viewForRow: ViewForRow
- /**
- - parameter components: Initial content value.
- - parameter numberOfComponents: Implementation of corresponding delegate method.
- - parameter numberOfRowsInComponent: Implementation of corresponding delegate method.
- - parameter attributedTitleForRow: Implementation of corresponding adapter method that converts component to `UIView`.
- */
- public init(components: Components,
- numberOfComponents: @escaping NumberOfComponents,
- numberOfRowsInComponent: @escaping NumberOfRowsInComponent,
- viewForRow: @escaping ViewForRow) {
- self.viewForRow = viewForRow
- super.init(components: components,
- numberOfComponents: numberOfComponents,
- numberOfRowsInComponent: numberOfRowsInComponent)
- }
-
- open func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
- return viewForRow(self, pickerView, components, row, component, view)
- }
- }
- /// A reactive UIPickerView data source
- open class RxPickerViewDataSource<Components>: NSObject, UIPickerViewDataSource {
- /**
- - parameter dataSource
- - parameter pickerView
- - parameter components
- */
- public typealias NumberOfComponents = (
- _ dataSource: RxPickerViewDataSource,
- _ pickerView: UIPickerView,
- _ components: Components) -> Int
- /**
- - parameter dataSource
- - parameter pickerView
- - parameter components
- - parameter component
- */
- public typealias NumberOfRowsInComponent = (
- _ dataSource: RxPickerViewDataSource,
- _ pickerView: UIPickerView,
- _ components: Components,
- _ component: Int
- ) -> Int
-
- fileprivate var components: Components
- /**
- - parameter components: Initial content value.
- - parameter numberOfComponents: Implementation of corresponding delegate method.
- - parameter numberOfRowsInComponent: Implementation of corresponding delegate method.
- */
- init(components: Components,
- numberOfComponents: @escaping NumberOfComponents,
- numberOfRowsInComponent: @escaping NumberOfRowsInComponent) {
- self.components = components
- self.numberOfComponents = numberOfComponents
- self.numberOfRowsInComponent = numberOfRowsInComponent
- super.init()
- }
-
- private let numberOfComponents: NumberOfComponents
- private let numberOfRowsInComponent: NumberOfRowsInComponent
-
- //MARK: UIPickerViewDataSource
-
- public func numberOfComponents(in pickerView: UIPickerView) -> Int {
- return numberOfComponents(self, pickerView, components)
- }
-
- public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
- return numberOfRowsInComponent(self, pickerView, components, component)
- }
- }
- extension RxPickerViewDataSource: RxPickerViewDataSourceType {
- public func pickerView(_ pickerView: UIPickerView, observedEvent: Event<Components>) {
- Binder(self) { (dataSource, components) in
- dataSource.components = components
- pickerView.reloadAllComponents()
- }.on(observedEvent)
- }
- }
- #endif
|