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 SwiftArray
s 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
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
numberOfComponents
callback, for instance, the closure you passed intonumberOfComponents
will be wiped out by this method and you will have to override that closure handler again.Important
Please remember that SwiftArray
s 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) -> Self
Parameters
strings
An
Array
ofString
s to be used for each row in a single component picker view.didSelect
A 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
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
numberOfComponents
callback, for instance, the closure you passed intonumberOfComponents
will be wiped out by this method and you will have to override that closure handler again.Important
Please remember that Swift
Array
s 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
add
methods 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) -> Self
Parameters
strings
An
Array
of any type to be used for each row in a single component picker view.rowTitle
A closure that is called when the UIPickerView needs to display a string for it’s row.
didSelect
A 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
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
numberOfComponents
callback, for instance, the closure you passed intonumberOfComponents
will be wiped out by this method and you will have to override that closure handler again.Important
Please remember that Swift
Array
s 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
add
methods 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) -> Self
Parameters
strings
An
Array
of any type to be used for each row in a single component picker view.rowView
A closure that is called when the UIPickerView needs to display a view for it’s row.
didSelect
A 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
numberOfComponents
callback, for instance, the closure you passed intonumberOfComponents
will be wiped out by this method and you will have to override that closure handler again.Important
Please remember that SwiftArray
s 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) -> Self
Parameters
strings
An
Array
ofArray
ofString
s 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]didSelect
A 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
numberOfComponents
callback, for instance, the closure you passed intonumberOfComponents
will be wiped out by this method and you will have to override that closure handler again.Important
Please remember that Swift
Array
s 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
add
methods 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) -> Self
Parameters
components
An
Array
ofArray
of 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]rowTitle
A closure that is called when the UIPickerView needs to display a string for it’s row.
didSelect
A 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
numberOfComponents
callback, for instance, the closure you passed intonumberOfComponents
will be wiped out by this method and you will have to override that closure handler again.Important
Please remember that Swift
Array
s 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
add
methods 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
Array
ofArray
of 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) -> Self
Parameters
rowView
A closure that is called when the UIPickerView needs to display a view for it’s row.
didSelect
A 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) -> Self
Parameters
handler
The 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) -> Self
Parameters
handler
The 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?) -> Self
Parameters
handler
The 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?) -> Self
Parameters
handler
The 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) -> Self
Parameters
handler
The 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) -> Self
Parameters
handler
The 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) -> Self
Parameters
handler
The 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) -> Self
Parameters
handler
The 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()