UIPickerView
extension UIPickerView
Delegate 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") }Declaration
Swift
@discardableResult public func addStrings(_ strings: [String], didSelect: @escaping (_ element: String, _ component: Int, _ row: Int) -> Void) -> SelfParameters
stringsAn
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 Value
itself 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") )Declaration
Swift
@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) -> SelfParameters
stringsAn
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 Value
itself 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") )Declaration
Swift
@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) -> SelfParameters
stringsAn
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 Value
itself 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") }Declaration
Swift
@discardableResult public func addComponents(_ strings: [[String]], didSelect: @escaping (_ element: String, _ component: Int, _ row: Int) -> Void) -> SelfParameters
stringsAn
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 Value
itself 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") )Declaration
Swift
@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) -> SelfParameters
componentsAn
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 Value
itself 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]Declaration
Swift
@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) -> SelfParameters
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 Value
itself so you can daisy chain the other delegate/datasource calls
-
Equivalent to implementing UIPickerViewDelegate’s pickerView(_:rowHeightForComponent:) method
Declaration
Swift
@discardableResult public func rowHeightForComponent(handler: @escaping (_ component: Int) -> CGFloat) -> SelfParameters
handlerThe closure that will be called in place of its equivalent delegate method
Return Value
itself so you can daisy chain the other delegate calls
-
Equivalent to implementing UIPickerViewDelegate’s pickerView(_:widthForComponent:) method
Declaration
Swift
@discardableResult public func widthForComponent(handler: @escaping (_ component: Int) -> CGFloat) -> SelfParameters
handlerThe closure that will be called in place of its equivalent delegate method
Return Value
itself so you can daisy chain the other delegate calls
-
Equivalent to implementing UIPickerViewDelegate’s pickerView(_:titleForRow:forComponent:) method
Declaration
Swift
@discardableResult public func titleForRow(handler: @escaping (_ row: Int, _ component: Int) -> String?) -> SelfParameters
handlerThe closure that will be called in place of its equivalent delegate method
Return Value
itself so you can daisy chain the other delegate calls
-
Equivalent to implementing UIPickerViewDelegate’s pickerView(_:attributedTitleForRow:forComponent:) method
Declaration
Swift
@discardableResult public func attributedTitleForRow(handler: @escaping (_ row: Int, _ component: Int) -> NSAttributedString?) -> SelfParameters
handlerThe closure that will be called in place of its equivalent delegate method
Return Value
itself so you can daisy chain the other delegate calls
-
Equivalent to implementing UIPickerViewDelegate’s pickerView(_:viewForRow:forComponent:reusing:) method
Declaration
Swift
@discardableResult public func viewForRow(handler: @escaping (_ row: Int, _ component: Int, _ reusingView: UIView?) -> UIView) -> SelfParameters
handlerThe closure that will be called in place of its equivalent delegate method
Return Value
itself so you can daisy chain the other delegate calls
-
Equivalent to implementing UIPickerViewDelegate’s pickerView(_:didSelectRow:inComponent:) method
Declaration
Swift
@discardableResult public func didSelectRow(handler: @escaping (_ row: Int, _ component: Int) -> Void) -> SelfParameters
handlerThe closure that will be called in place of its equivalent delegate method
Return Value
itself so you can daisy chain the other delegate calls
-
Equivalent to implementing UIPickerViewDataSource’s numberOfComponents(in:) method
Declaration
Swift
@discardableResult public func numberOfComponents(handler: @escaping () -> Int) -> SelfParameters
handlerThe closure that will be called in place of its equivalent dataSource method
Return Value
itself so you can daisy chain the other dataSource calls
-
Equivalent to implementing UIPickerViewDataSource’s pickerView(_:numberOfRowsInComponent:) method
Declaration
Swift
@discardableResult public func numberOfRowsInComponent(handler: @escaping (_ component: Int) -> Int) -> SelfParameters
handlerThe closure that will be called in place of its equivalent dataSource method
Return Value
itself 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.Declaration
Swift
@objc public func clearClosureDelegates()
View on GitHub
UIPickerView Extension Reference