UIPickerView
extension UIPickerViewDelegate and DataSource
UIPickerView closures make it easy to implement UIPickerViewDelegate and
 UIPickerViewDataSource protocol methods in an organized way. The following
 is an example of a simple collection view that displays strings in each row.
func loadPickerView() {
    pickerView
        .numberOfRowsInComponent() { _ in
            countries.count
        }.titleForRow() { row, component in
            countries[row]
        }.didSelectRow { row, component in
            log("\(countries[row]) selected")
        }.reloadAllComponents()
}
Arrays
These operations are common. Usually, they involve populating the UIPickerView
 with the values from an array. Closures framework gives you a convenient
 way to pass your collection to the table view, so that it can perform the boilerplate
 operations for you, especially the ones that are required to make the picker
 view perform at a basic level.
Important
Please remember that SwiftArrays are value types. This means that they
are copied when mutaded. When the values or sequence of your array changes, you will
need to call one of the add methods again, just before you
call reloadData().
func loadPickerView(countries: [String]) {
    let reversed = Array(countries.reversed())
    pickerView
        .addStrings(reversed) { country,component,row in
            log("\(country) selected from array")
        }.reloadAllComponents()
}
Note
Be sure to note that most of the closure callbacks in these array binding methods switch the order of the parameters of row and component. Most of theUIPickerView delegate/datasource method parameters pass row,component. The
parameters on the add methods switch the order and send component,row
Multiple Components
And finally, you can just as easily show mutliple components by binding a 2-dimensional array. When using this method, the outer dimension of the array is the component (columns) and the inner dimension are the rows in that component.
let anElement = myTwoDArray[component][row]
In this example, the more verbose row handler is provided just to show the different variations. Adding multiple components has a convenient method to deal with string only arrays also.
func loadPickerView(components: [[String]]) {
    pickerView.addComponents(
        components,
        rowTitle: { country,component,row in
            country},
        didSelect: { country,component,row in
            log("\(country) selected from 2D Array")
    })
    /**
     This also allows you to override any default behavior so
     you aren't overly committed, even though you're initially binding everything
     to the `Array`.
     */
    pickerView.widthForComponent { component in
        component ==  0 ? 200 : 100
    }.reloadAllComponents()
}
- 
                  
                  This method defaults many of the boilerplate callbacks needed to populate a UIPickerView when using an Arrayas a data source. The defaults that this method takes care of:- Provides the number of components
- Provides the number of rows
- Handles the pickerView(_:didSelectRow:inComponent:) delegate method
- Provides the title string for each row
 This method simply sets basic default behavior. This means that you can override the default picker view handlers after this method is called. However, remember that order matters. If you call this method after you override the numberOfComponentscallback, for instance, the closure you passed intonumberOfComponentswill be wiped out by this method and you will have to override that closure handler again.Important Please remember that SwiftArrays are value types. This means that they are copied when mutaded. When the values or sequence of your array changes, you will need to call this method again, just before you call reloadComponent() or reloadAllComponents(). If you have a lot of picker view customization in addtion to a lot of updates to your array, it is more appropriate to use the individual closure handlers instead of this method.
 An example of calling this method:pickerView.addStrings(<#myArray#>) { aTitle,component,row in print("\(aTitle) was selected") }DeclarationSwift @discardableResult public func addStrings(_ strings: [String], didSelect: @escaping (_ element: String, _ component: Int, _ row: Int) -> Void) -> SelfParametersstringsAn ArrayofStrings to be used for each row in a single component picker view.didSelectA closure that is called when the UIPickerView’s value has been selected. Return Valueitself so you can daisy chain the other delegate/datasource calls 
- 
                  
                  This method defaults many of the boilerplate callbacks needed to populate a UIPickerView when using an Arrayas a data source. The defaults that this method takes care of:- Provides the number of components
- Provides the number of rows
- Handles the pickerView(_:titleForRow:forComponent:) delegate method
- Handles the pickerView(_:didSelectRow:inComponent:) delegate method
 This method simply sets basic default behavior. This means that you can override the default picker view handlers after this method is called. However, remember that order matters. If you call this method after you override the numberOfComponentscallback, for instance, the closure you passed intonumberOfComponentswill be wiped out by this method and you will have to override that closure handler again.Important Please remember that Swift Arrays are value types. This means that they are copied when mutaded. When the values or sequence of your array changes, you will need to call this method again, just before you call reloadComponent() or reloadAllComponents(). If you have a lot of picker view customization in addtion to a lot of updates to your array, it is more appropriate to use the individual closure handlers instead of this method.Important Be sure to note that most of the closure callbacks in these array binding methods switch the order of the parameters of row and component. Most of the UIPickerView delegate/datasource method parameters have row,component. The handlers’ parameters on the addmethods send component,row.
 An example of calling this method:pickerView.addElements( <#myArray#>, rowTitle: { element, component, row in return <#aTitle(from: element)#>}, didSelect: { element, component, row in print("\(element) was selected") )DeclarationSwift @discardableResult public func addElements<Element>(_ elements: [Element], rowTitle: @escaping (_ element: Element, _ component: Int, _ row: Int) -> String, didSelect: @escaping (_ element: Element, _ component: Int, _ row: Int) -> Void) -> SelfParametersstringsAn Arrayof any type to be used for each row in a single component picker view.rowTitleA closure that is called when the UIPickerView needs to display a string for it’s row. didSelectA closure that is called when the UIPickerView’s value has been selected. Return Valueitself so you can daisy chain the other delegate/datasource calls 
- 
                  
                  This method defaults many of the boilerplate callbacks needed to populate a UIPickerView when using an Arrayas a data source. The defaults that this method takes care of:- Provides the number of components
- Provides the number of rows
- Handles the pickerView(_:viewForRow:forComponent:) delegate method
- Handles the pickerView(_:didSelectRow:inComponent:) delegate method
 This method simply sets basic default behavior. This means that you can override the default picker view handlers after this method is called. However, remember that order matters. If you call this method after you override the numberOfComponentscallback, for instance, the closure you passed intonumberOfComponentswill be wiped out by this method and you will have to override that closure handler again.Important Please remember that Swift Arrays are value types. This means that they are copied when mutaded. When the values or sequence of your array changes, you will need to call this method again, just before you call reloadComponent() or reloadAllComponents(). If you have a lot of picker view customization in addtion to a lot of updates to your array, it is more appropriate to use the individual closure handlers instead of this method.Important Be sure to note that most of the closure callbacks in these array binding methods switch the order of the parameters of row and component. Most of the UIPickerView delegate/datasource method parameters have row,component. The handlers’ parameters on the addmethods send component,row.
 An example of calling this method:pickerView.addElements( <#myArray#>, rowView: { element, reuseView, component, row in return <#aView(from: element)#>}, didSelect: { element, component, row in print("\(element) was selected") )DeclarationSwift @discardableResult public func addElements<Element>(_ elements: [Element], rowView: @escaping (_ element: Element, _ reuseView: UIView?, _ component: Int, _ row: Int) -> UIView, didSelect: @escaping (_ element: Element, _ component: Int, _ row: Int) -> Void) -> SelfParametersstringsAn Arrayof any type to be used for each row in a single component picker view.rowViewA closure that is called when the UIPickerView needs to display a view for it’s row. didSelectA closure that is called when the UIPickerView’s value has been selected. Return Valueitself so you can daisy chain the other delegate/datasource calls 
- 
                  
                  This method defaults many of the boilerplate callbacks needed to populate a UIPickerView when using a two-dimensional Array as a data source. The defaults that this method takes care of: - Provides the number of components
- Provides the number of rows
- Handles the pickerView(_:didSelectRow:inComponent:) delegate method
- Provides the title string for each row
 This method simply sets basic default behavior. This means that you can override the default picker view handlers after this method is called. However, remember that order matters. If you call this method after you override the numberOfComponentscallback, for instance, the closure you passed intonumberOfComponentswill be wiped out by this method and you will have to override that closure handler again.Important Please remember that SwiftArrays are value types. This means that they are copied when mutaded. When the values or sequence of your array changes, you will need to call this method again, just before you call reloadComponent() or reloadAllComponents(). If you have a lot of picker view customization in addtion to a lot of updates to your array, it is more appropriate to use the individual closure handlers instead of this method.
 An example of calling this method:pickerView.addComponents(<#my2DArray#>) { aTitle,component,row in print("\(aTitle) was selected") }DeclarationSwift @discardableResult public func addComponents(_ strings: [[String]], didSelect: @escaping (_ element: String, _ component: Int, _ row: Int) -> Void) -> SelfParametersstringsAn ArrayofArrayofStrings to be used for each row and component in a picker view. The outer dimension of the array is the component (columns) and the inner dimension are the rows in that component. e.g. myTwoDArray[component][row]didSelectA closure that is called when the UIPickerView’s value has been selected. Return Valueitself so you can daisy chain the other delegate/datasource calls 
- 
                  
                  This method defaults many of the boilerplate callbacks needed to populate a UIPickerView when using a two-dimensional Array as a data source. The defaults that this method takes care of: - Provides the number of components
- Provides the number of rows
- Handles the pickerView(_:titleForRow:forComponent:) delegate method
- Handles the pickerView(_:didSelectRow:inComponent:) delegate method
 This method simply sets basic default behavior. This means that you can override the default picker view handlers after this method is called. However, remember that order matters. If you call this method after you override the numberOfComponentscallback, for instance, the closure you passed intonumberOfComponentswill be wiped out by this method and you will have to override that closure handler again.Important Please remember that Swift Arrays are value types. This means that they are copied when mutaded. When the values or sequence of your array changes, you will need to call this method again, just before you call reloadComponent() or reloadAllComponents(). If you have a lot of picker view customization in addtion to a lot of updates to your array, it is more appropriate to use the individual closure handlers instead of this method.Important Be sure to note that most of the closure callbacks in these array binding methods switch the order of the parameters of row and component. Most of the UIPickerView delegate/datasource method parameters have row,component. The handlers’ parameters on the addmethods send component,row.
 An example of calling this method:pickerView.addComponents( <#my2DArray#>, rowTitle: { element, component, row in return <#aTitle(from: element, componentIdx: component)#>}, didSelect: { element, component, row in print("\(element) was selected") )DeclarationSwift @discardableResult public func addComponents<Element>(_ components: [[Element]], rowTitle: @escaping (_ element: Element, _ component: Int, _ row: Int) -> String, didSelect: @escaping (_ element: Element, _ component: Int, _ row: Int) -> Void) -> SelfParameterscomponentsAn ArrayofArrayof any type to be used for each row and component in a picker view. The outer dimension of the array is the component (columns) and the inner dimension are the rows in that component. e.g. myTwoDArray[component][row]rowTitleA closure that is called when the UIPickerView needs to display a string for it’s row. didSelectA closure that is called when the UIPickerView’s value has been selected. Return Valueitself so you can daisy chain the other delegate/datasource calls 
- 
                  
                  This method defaults many of the boilerplate callbacks needed to populate a UIPickerView when using a two-dimensional Array as a data source. The defaults that this method takes care of: - Provides the number of components
- Provides the number of rows
- Handles the pickerView(_:viewForRow:forComponent:) delegate method
- Handles the pickerView(_:didSelectRow:inComponent:) delegate method
 This method simply sets basic default behavior. This means that you can override the default picker view handlers after this method is called. However, remember that order matters. If you call this method after you override the numberOfComponentscallback, for instance, the closure you passed intonumberOfComponentswill be wiped out by this method and you will have to override that closure handler again.Important Please remember that Swift Arrays are value types. This means that they are copied when mutaded. When the values or sequence of your array changes, you will need to call this method again, just before you call reloadComponent() or reloadAllComponents(). If you have a lot of picker view customization in addtion to a lot of updates to your array, it is more appropriate to use the individual closure handlers instead of this method.Important Be sure to note that most of the closure callbacks in these array binding methods switch the order of the parameters of row and component. Most of the UIPickerView delegate/datasource method parameters have row,component. The handlers’ parameters on the addmethods send component,row.
 An example of calling this method:pickerView.addComponents( <#my2DArray#>, rowView: { element, reuseView, component, row in return <#aView(from: element, componentIdx: component)#>}, didSelect: { element, component, row in print("\(element) was selected") )parameter components: An ArrayofArrayof any type to be used for each row and component in a picker view. The outer dimension of the array is the component (columns) and the inner dimension are the rows in that component. e.g. myTwoDArray[component][row]DeclarationSwift @discardableResult public func addComponents<Element>(_ components: [[Element]], rowView: @escaping (_ element: Element, _ reuseView: UIView?, _ component: Int, _ row: Int) -> UIView, didSelect: @escaping (_ element: Element, _ component: Int, _ row: Int) -> Void) -> SelfParametersrowViewA closure that is called when the UIPickerView needs to display a view for it’s row. didSelectA closure that is called when the UIPickerView’s value has been selected. Return Valueitself so you can daisy chain the other delegate/datasource calls 
- 
                  
                  Equivalent to implementing UIPickerViewDelegate’s pickerView(_:rowHeightForComponent:) method DeclarationSwift @discardableResult public func rowHeightForComponent(handler: @escaping (_ component: Int) -> CGFloat) -> SelfParametershandlerThe closure that will be called in place of its equivalent delegate method Return Valueitself so you can daisy chain the other delegate calls 
- 
                  
                  Equivalent to implementing UIPickerViewDelegate’s pickerView(_:widthForComponent:) method DeclarationSwift @discardableResult public func widthForComponent(handler: @escaping (_ component: Int) -> CGFloat) -> SelfParametershandlerThe closure that will be called in place of its equivalent delegate method Return Valueitself so you can daisy chain the other delegate calls 
- 
                  
                  Equivalent to implementing UIPickerViewDelegate’s pickerView(_:titleForRow:forComponent:) method DeclarationSwift @discardableResult public func titleForRow(handler: @escaping (_ row: Int, _ component: Int) -> String?) -> SelfParametershandlerThe closure that will be called in place of its equivalent delegate method Return Valueitself so you can daisy chain the other delegate calls 
- 
                  
                  Equivalent to implementing UIPickerViewDelegate’s pickerView(_:attributedTitleForRow:forComponent:) method DeclarationSwift @discardableResult public func attributedTitleForRow(handler: @escaping (_ row: Int, _ component: Int) -> NSAttributedString?) -> SelfParametershandlerThe closure that will be called in place of its equivalent delegate method Return Valueitself so you can daisy chain the other delegate calls 
- 
                  
                  Equivalent to implementing UIPickerViewDelegate’s pickerView(_:viewForRow:forComponent:reusing:) method DeclarationSwift @discardableResult public func viewForRow(handler: @escaping (_ row: Int, _ component: Int, _ reusingView: UIView?) -> UIView) -> SelfParametershandlerThe closure that will be called in place of its equivalent delegate method Return Valueitself so you can daisy chain the other delegate calls 
- 
                  
                  Equivalent to implementing UIPickerViewDelegate’s pickerView(_:didSelectRow:inComponent:) method DeclarationSwift @discardableResult public func didSelectRow(handler: @escaping (_ row: Int, _ component: Int) -> Void) -> SelfParametershandlerThe closure that will be called in place of its equivalent delegate method Return Valueitself so you can daisy chain the other delegate calls 
- 
                  
                  Equivalent to implementing UIPickerViewDataSource’s numberOfComponents(in:) method DeclarationSwift @discardableResult public func numberOfComponents(handler: @escaping () -> Int) -> SelfParametershandlerThe closure that will be called in place of its equivalent dataSource method Return Valueitself so you can daisy chain the other dataSource calls 
- 
                  
                  Equivalent to implementing UIPickerViewDataSource’s pickerView(_:numberOfRowsInComponent:) method DeclarationSwift @discardableResult public func numberOfRowsInComponent(handler: @escaping (_ component: Int) -> Int) -> SelfParametershandlerThe closure that will be called in place of its equivalent dataSource method Return Valueitself so you can daisy chain the other dataSource calls 
- 
                  
                  Clears any delegate/dataSource closures that were assigned to this UIPickerView. This cleans up memory as well as sets the delegate/dataSource properties to nil. This is typically only used for explicit cleanup. You are not required to call this method.DeclarationSwift @objc public func clearClosureDelegates()
 View on GitHub
View on GitHub UIPickerView Extension Reference
        UIPickerView Extension Reference