UIPickerView
UIPickerView a view that uses a spinning-wheel to show one or more sets of values.
UIDatePicker built-in control based on UIPickerView to select date and time. Since iOS 14+ you can select other style, not only wheel.
UIPickerViewDataSource provides information about data:
- numberOfComponents(UIPickerView) - the number of components (i.e. columns).
- pickerView(UIPickerView, numberOfRowsInComponent: Int) - the number of rows for a specified component.
UIPickerViewDelegate allows to specify size and content of items. Most useful methods:
- pickerView(UIPickerView, titleForRow, forComponent) - provides title to use for a given row in a given component.
- pickerView(UIPickerView, didSelectRow, inComponent) - called by the picker view when the user selects a row in a component.
Infinite UIPickerView
class MyViewController: UIViewController {
private let pickerViewData = ["title_1", "title_2", ..., "title_n"]
private let pickerViewRows = 100_000
private let pickerViewMiddle =
((pickerViewRows / pickerViewData.count) / 2) * pickerViewData.count
// ...
override func viewDidLoad() {
self.picker.delegate = self
self.picker.dataSource = self
let initialValue = 0
if let row = rowForValue(initialValue) {
self.picker.selectRow(row, inComponent: 0, animated: false)
}
}
}
extension MyViewController : UIPickerViewDataSource {
func rowForValue(value: Int) -> Int? {
if let valueIndex = find(pickerViewData, value) {
return pickerViewMiddle + value
}
return nil
}
func pickerView(pickerView: UIPickerView,
titleForRow row: Int,
forComponent component: Int) -> String! {
// use % for looping
return "\(pickerViewData[row % pickerViewData.count])"
}
}
extension MyViewController : UIPickerViewDelegate {
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView,
numberOfRowsInComponent component: Int) -> Int {
return pickerViewRows
}
func pickerView(pickerView: UIPickerView,
didSelectRow row: Int,
inComponent component: Int) {
// ...
// reset current item
// to the closest to the middle
let newRow = pickerViewMiddle + (row % pickerViewData.count)
pickerView.selectRow(newRow, inComponent: 0, animated: false)
}
}