RxPickerViewAdapter.swift 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. //
  2. // RxPickerViewAdapter.swift
  3. // RxDataSources
  4. //
  5. // Created by Sergey Shulga on 04/07/2017.
  6. // Copyright © 2017 kzaher. All rights reserved.
  7. //
  8. #if os(iOS)
  9. import Foundation
  10. import UIKit
  11. #if !RX_NO_MODULE
  12. import RxSwift
  13. import RxCocoa
  14. #endif
  15. /// A reactive UIPickerView adapter which uses `func pickerView(UIPickerView, titleForRow: Int, forComponent: Int)` to display the content
  16. /**
  17. Example:
  18. let adapter = RxPickerViewStringAdapter<[T]>(...)
  19. items
  20. .bind(to: firstPickerView.rx.items(adapter: adapter))
  21. .disposed(by: disposeBag)
  22. */
  23. open class RxPickerViewStringAdapter<Components>: RxPickerViewDataSource<Components>, UIPickerViewDelegate {
  24. /**
  25. - parameter dataSource
  26. - parameter pickerView
  27. - parameter components
  28. - parameter row
  29. - parameter component
  30. */
  31. public typealias TitleForRow = (
  32. _ dataSource: RxPickerViewStringAdapter<Components>,
  33. _ pickerView: UIPickerView,
  34. _ components: Components,
  35. _ row: Int,
  36. _ component: Int
  37. ) -> String?
  38. private let titleForRow: TitleForRow
  39. /**
  40. - parameter components: Initial content value.
  41. - parameter numberOfComponents: Implementation of corresponding delegate method.
  42. - parameter numberOfRowsInComponent: Implementation of corresponding delegate method.
  43. - parameter titleForRow: Implementation of corresponding adapter method that converts component to `String`.
  44. */
  45. public init(components: Components,
  46. numberOfComponents: @escaping NumberOfComponents,
  47. numberOfRowsInComponent: @escaping NumberOfRowsInComponent,
  48. titleForRow: @escaping TitleForRow) {
  49. self.titleForRow = titleForRow
  50. super.init(components: components,
  51. numberOfComponents: numberOfComponents,
  52. numberOfRowsInComponent: numberOfRowsInComponent)
  53. }
  54. open func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
  55. return titleForRow(self, pickerView, components, row, component)
  56. }
  57. }
  58. /// A reactive UIPickerView adapter which uses `func pickerView(UIPickerView, viewForRow: Int, forComponent: Int, reusing: UIView?)` to display the content
  59. /**
  60. Example:
  61. let adapter = RxPickerViewAttributedStringAdapter<[T]>(...)
  62. items
  63. .bind(to: firstPickerView.rx.items(adapter: adapter))
  64. .disposed(by: disposeBag)
  65. */
  66. open class RxPickerViewAttributedStringAdapter<Components>: RxPickerViewDataSource<Components>, UIPickerViewDelegate {
  67. /**
  68. - parameter dataSource
  69. - parameter pickerView
  70. - parameter components
  71. - parameter row
  72. - parameter component
  73. */
  74. public typealias AttributedTitleForRow = (
  75. _ dataSource: RxPickerViewAttributedStringAdapter<Components>,
  76. _ pickerView: UIPickerView,
  77. _ components: Components,
  78. _ row: Int,
  79. _ component: Int
  80. ) -> NSAttributedString?
  81. private let attributedTitleForRow: AttributedTitleForRow
  82. /**
  83. - parameter components: Initial content value.
  84. - parameter numberOfComponents: Implementation of corresponding delegate method.
  85. - parameter numberOfRowsInComponent: Implementation of corresponding delegate method.
  86. - parameter attributedTitleForRow: Implementation of corresponding adapter method that converts component to `NSAttributedString`.
  87. */
  88. public init(components: Components,
  89. numberOfComponents: @escaping NumberOfComponents,
  90. numberOfRowsInComponent: @escaping NumberOfRowsInComponent,
  91. attributedTitleForRow: @escaping AttributedTitleForRow) {
  92. self.attributedTitleForRow = attributedTitleForRow
  93. super.init(components: components,
  94. numberOfComponents: numberOfComponents,
  95. numberOfRowsInComponent: numberOfRowsInComponent)
  96. }
  97. open func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
  98. return attributedTitleForRow(self, pickerView, components, row, component)
  99. }
  100. }
  101. /// A reactive UIPickerView adapter which uses `func pickerView(pickerView:, viewForRow row:, forComponent component:)` to display the content
  102. /**
  103. Example:
  104. let adapter = RxPickerViewViewAdapter<[T]>(...)
  105. items
  106. .bind(to: firstPickerView.rx.items(adapter: adapter))
  107. .disposed(by: disposeBag)
  108. */
  109. open class RxPickerViewViewAdapter<Components>: RxPickerViewDataSource<Components>, UIPickerViewDelegate {
  110. /**
  111. - parameter dataSource
  112. - parameter pickerView
  113. - parameter components
  114. - parameter row
  115. - parameter component
  116. - parameter view
  117. */
  118. public typealias ViewForRow = (
  119. _ dataSource: RxPickerViewViewAdapter<Components>,
  120. _ pickerView: UIPickerView,
  121. _ components: Components,
  122. _ row: Int,
  123. _ component: Int,
  124. _ view: UIView?
  125. ) -> UIView
  126. private let viewForRow: ViewForRow
  127. /**
  128. - parameter components: Initial content value.
  129. - parameter numberOfComponents: Implementation of corresponding delegate method.
  130. - parameter numberOfRowsInComponent: Implementation of corresponding delegate method.
  131. - parameter attributedTitleForRow: Implementation of corresponding adapter method that converts component to `UIView`.
  132. */
  133. public init(components: Components,
  134. numberOfComponents: @escaping NumberOfComponents,
  135. numberOfRowsInComponent: @escaping NumberOfRowsInComponent,
  136. viewForRow: @escaping ViewForRow) {
  137. self.viewForRow = viewForRow
  138. super.init(components: components,
  139. numberOfComponents: numberOfComponents,
  140. numberOfRowsInComponent: numberOfRowsInComponent)
  141. }
  142. open func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
  143. return viewForRow(self, pickerView, components, row, component, view)
  144. }
  145. }
  146. /// A reactive UIPickerView data source
  147. open class RxPickerViewDataSource<Components>: NSObject, UIPickerViewDataSource {
  148. /**
  149. - parameter dataSource
  150. - parameter pickerView
  151. - parameter components
  152. */
  153. public typealias NumberOfComponents = (
  154. _ dataSource: RxPickerViewDataSource,
  155. _ pickerView: UIPickerView,
  156. _ components: Components) -> Int
  157. /**
  158. - parameter dataSource
  159. - parameter pickerView
  160. - parameter components
  161. - parameter component
  162. */
  163. public typealias NumberOfRowsInComponent = (
  164. _ dataSource: RxPickerViewDataSource,
  165. _ pickerView: UIPickerView,
  166. _ components: Components,
  167. _ component: Int
  168. ) -> Int
  169. fileprivate var components: Components
  170. /**
  171. - parameter components: Initial content value.
  172. - parameter numberOfComponents: Implementation of corresponding delegate method.
  173. - parameter numberOfRowsInComponent: Implementation of corresponding delegate method.
  174. */
  175. init(components: Components,
  176. numberOfComponents: @escaping NumberOfComponents,
  177. numberOfRowsInComponent: @escaping NumberOfRowsInComponent) {
  178. self.components = components
  179. self.numberOfComponents = numberOfComponents
  180. self.numberOfRowsInComponent = numberOfRowsInComponent
  181. super.init()
  182. }
  183. private let numberOfComponents: NumberOfComponents
  184. private let numberOfRowsInComponent: NumberOfRowsInComponent
  185. //MARK: UIPickerViewDataSource
  186. public func numberOfComponents(in pickerView: UIPickerView) -> Int {
  187. return numberOfComponents(self, pickerView, components)
  188. }
  189. public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
  190. return numberOfRowsInComponent(self, pickerView, components, component)
  191. }
  192. }
  193. extension RxPickerViewDataSource: RxPickerViewDataSourceType {
  194. public func pickerView(_ pickerView: UIPickerView, observedEvent: Event<Components>) {
  195. Binder(self) { (dataSource, components) in
  196. dataSource.components = components
  197. pickerView.reloadAllComponents()
  198. }.on(observedEvent)
  199. }
  200. }
  201. #endif