When using a dictionary to populate a UIPickerView in Swift, how do I specify that the key is to be used as the title for row, while the value is used to perform calculations, such as to set the value for selectedPower, below?
If I were using an array of floats, I'd set it up as below, but how do I do it with a dictionary?
class DiagnosticORViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
var selectedPower : Float!
let FitAssessment : [String : Float] = ["0.50 flat" : -0.50, "0.25 flat" : -0.25, "aligned" : 0, "0.25 steep" : 0.25, "0.50 steep" : 0.50]
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return FitAssessment.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
return "\(FitAssessment[row])"
}
func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int) {
selectedPower = FitAssessment[row]
}
Two separate arrays solves the problem.
class DiagnosticORViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
var selectedPower : Float!
let FitDescription : [String] = ["0.50 flat", "0.25 flat", "aligned", "0.25 steep", "0.50 steep"]
let FitValue : [Float] = [ -0.50, -0.25, 0, 0.25, 0.50]
#IBOutlet weak var fitAssessmentPicker: UIPickerView!
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return FitDescription.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
return FitDescription[row]
}
func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int) {
selectedPower = FitValue[row]
}
This morning I had a similar issue.
Since I am reading data from data-base, and fill the picker, I also need IDs of such data.
I will paste a very basic code on how to realize your question with a stupid example I came with:
P.S. It might be late for you, but might be useful for someone else.
import UIKit
class selectLanguage: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource
{
var pickerData = [String:Int]()
#IBOutlet weak var pickerControl: UIPickerView!
override func viewDidLoad()
{
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
pickerData["English"] = 0
pickerData["German"] = 1
pickerData["Serbian"] = 2
pickerData["French"] = 3
pickerData["Italian"] = 4
self.pickerControl.delegate = self
self.pickerControl.dataSource = self
}
// Connect data to picker:
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// The number of columns of data
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
// The number of rows of data
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerData.count
}
// The data to return for the row and component (column) that's being passed in
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
// builtInCommands[pickerData[row]]
return "\(Array(pickerData.keys)[row])"
}
//Results of selection
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let key = Array(pickerData.keys)[row]
let value = pickerData[key]
print(">>>Selected Language is: \(key), and its id is : \(value!)")
}
}
Dictionaries are unordered, so it is better to use an Array of named tuples
let FitAssessment:[(myKey: String, myValue: Double)] = [("0.50 flat", -0.50), ("0.25 flat", -0.25), (etc....)]
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return FitAssessment.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
return FitAssessment[row].myName
}
func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int) {
selectedPower = FitAssessment[row].myValue
}
Related
When I tap on the textField, the input area appear, but there's only 1 row, with blank content. (I expect 3 rows: a,b and c)
I changed the returned value in numberOfRowsInComponent and titleForRow functions to constants, but get the same result (1 blank row). Maybe, these 2 functions never be called.
Please help me!
//In ViewDidLoad Function (ViewController.swift):
let myPickerView: MyPickerView = MyPickerView(arrData: ["a","b","c"]){ selected in
print(selected)
}
textField.inputView = myPickerView.picker
//In MyPickerView.swift
class MyPickerView: NSObject, UIPickerViewDelegate, UIPickerViewDataSource {
var arrData: Array<String>
var picker: UIPickerView
var action: (_ selected: String) -> Void
public init(
arrData: Array<String>,
action: #escaping (_ selected: String) -> Void
) {
self.arrData = arrData
self.action = action
self.picker = UIPickerView()
super.init()
self.picker.delegate = self
self.picker.dataSource = self
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return self.arrData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return self.arrData[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
self.action(self.arrData[row])
}
}
I found the problem. When I changed myPickerView to global variable (put outside of ViewDidLoad), everything fined.
var myPickerView: MyPickerView?
//In ViewDidload
myPickerView = MyPickerView(arrData: ["a","b","c"]){ selected in
print(selected)
}
I need some help. I've been looking for the solution for two days.
class Mam_sEntre_eViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
let notes = [0, 1, 2, 3, 4, 5]
#IBOutlet weak var noteGoutPickerView: UIPickerView!
#IBAction func validate() {
validateNoteMam_sEntre_e()
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return notes.count
}
private func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> Int? {
return notes[row]
}
private func validateNoteMam_sEntre_e() {
let noteGoutIndex = noteGoutPickerView.selectedRow(inComponent: 0)
let noteGout = notes[noteGoutIndex]
}
}
Change
private func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> Int? {
return notes[row]
}
To
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return String(notes[row])
}
Not private, return String not Int. See https://developer.apple.com/documentation/uikit/uipickerviewdelegate/1614384-pickerview
I am trying to get the second picker to display the array I created, but it won't and I have been messing with it for hours. Any ideas?
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return aircraft.count
}
#IBOutlet weak var aircraftType: UIPickerView!
#IBOutlet weak var model: UIPickerView!
let aircraft = ["Airbus", "Boeing", "Bombardier", "Embraer"]
let models = [ "Airbus": ["A300", "A320", "A330", "A350", "A380"], "Boeing": ["737", "747", "757/767", "777", "787"], "Bombardier": ["CRJ200", "CRJ700/900"], "Embraer": ["ERJ145", "ERJ170", "ERJ190"] ]
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 2
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return aircraft [row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
}
Please find the updated code. You should reload pickerview component on select of Aircrafts. Do please take of optional bindings
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == 0 {
return aircraft.count
}
else {
return (models[aircraft[aircraftType.selectedRow(inComponent: 0)]]?.count)!
}
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 2
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == 0 {
return aircraft [row]
}
else {
return models[aircraft[aircraftType.selectedRow(inComponent: 0)]]?[row]
}
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if component == 0 {
aircraftType.reloadComponent(1)
}
}
I try to use this method selectedRow(inComponent: 0), yet it doesn't work for me. Any way out to get the first/default value from picker when it is not active?
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return countries.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return countries[row].name
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
country.text = countries[row].name //`country.text` is just textField
}
}
Not a big deal-
Just define your picker view as global and access the value for objectAtIndex(0)
And write this line of code in viewDidLoad()
Not exact, but something like this-
#IBOutlet var yourPicker: UIPickerView! = UIPickerView()
var yourArray = ["Apple", "Samsung", "Nokia"]
override func viewDidLoad() {
super.viewDidLoad()
yourPicker.text = yourArray[0]
}
I have error with using UIPickerView
SelectViewController.swift:35:10: Method 'pickerView(pickerView:numberOfRowsInComponent:)' has different argument names from those required by protocol 'UIPickerViewDataSource' ('pickerView(_:numberOfRowsInComponent:)')
I set UIPickerView on Storyboard and attached this to the songPicker variable.
and then I think I integrated the functions necessary though, it showed error like this.
I found out that structure of picker view is changed on the version of swift.
However can't find the correct answer yet.
My swift is 3.1
Does anyone help me?
class SelectViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate{
#IBOutlet weak var songPicker: UIPickerView!
let songNames = ["test","test2"]
override func viewDidLoad(){
songPicker.delegate = self
songPicker.dataSource = self
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return songNames.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int) -> String? {
return songNames[row]
}
override func didReceiveMemoryWarning() {
}
}
try this code
class ElibraryViewController: UIViewController, UIPickerViewDelegate,UIPickerViewDataSource {
#IBOutlet weak var txtTitle: UITextField!
#IBOutlet weak var Picker: UIPickerView!
let songNames = ["test","test2"]
override func viewDidLoad()
{
super.viewDidLoad()
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?
{
return songNames[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
{
let obj = songNames[row]
txtTitle.text = obj
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int
{
return songNames.count
}
override func didReceiveMemoryWarning() {
}
}
Use this method, see the use of _ before pickerview. That is the only problem
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
}
UIPickerViewDataSource is changes in swift 3 and above.
Updated syntax:-
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return arrayData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return arrayData[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
}
Have a look at apple documentation (SO reference).
I recommend you to use IQDropDownTextField - Click Here