I used a UIPickerView with four components to enter digits without a keyboard. I added a decimal point, with just a '.' in a UILabelView. See the screen to get the idea.
My code is for the UIPickerView is:
func numberOfComponents(in weightPickerView: UIPickerView) -> Int {
return 4
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return loopingMargin * numbers.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return numbers[row % numbers.count]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let currentIndex = row % numbers.count
digits[component] = currentIndex
let weightString = "\(digits[0])\(digits[1]).\(digits[2])\(digits[3])"
weightField.text = weightString
}
And inside viewDidLoad() part of the code is:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
weightPickerView.dataSource = self
weightPickerView.delegate = self
weightPickerView.selectRow((loopingMargin / 2) * numbers.count, inComponent: 0, animated: false)
weightPickerView.selectRow((loopingMargin / 2) * numbers.count, inComponent: 1, animated: false)
weightPickerView.selectRow((loopingMargin / 2) * numbers.count, inComponent: 2, animated: false)
weightPickerView.selectRow((loopingMargin / 2) * numbers.count, inComponent: 3, animated: false)
}
My question... I would like to add a fifth component with only a '.' in it (so the space gets evenly distributed). How can I do that?
You just need to update your picker view methods to provide the extra component. Assuming you want it in the middle, your code needs to be:
func numberOfComponents(in weightPickerView: UIPickerView) -> Int {
return 5
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return component == 2 ? 1 : loopingMargin * numbers.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return component == 2 ? "." : numbers[row % numbers.count]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if component != 2 {
var index = component
if component > 2 {
index -= 1
}
let currentIndex = row % numbers.count
digits[index] = currentIndex
let weightString = "\(digits[0])\(digits[1]).\(digits[2])\(digits[3])"
weightField.text = weightString
}
}
override func viewDidLoad() {
super.viewDidLoad()
weightPickerView.dataSource = self
weightPickerView.delegate = self
weightPickerView.selectRow((loopingMargin / 2) * numbers.count, inComponent: 0, animated: false)
weightPickerView.selectRow((loopingMargin / 2) * numbers.count, inComponent: 1, animated: false)
weightPickerView.selectRow((loopingMargin / 2) * numbers.count, inComponent: 3, animated: false)
weightPickerView.selectRow((loopingMargin / 2) * numbers.count, inComponent: 4, animated: false)
}
Assuming the .
represents a decimal separator, keep in mind that many users around the world don't use .
for a decimal separator. So you really should show the appropriate character. You can get the decimalSeparator
property of a NumberFormatter
.