0

I am trying to follow the following solution to having multiple UIPickerViews on the one UIViewController. They suggest that a tag for each of the UITextfield which I have done and able to implement the number of rows, title for row and number of components. However, I have reached a stumbling block when implementing the did select row. When I select the UITextField it highlights another UITextfield. Below is the code I have so far. class DriverViewController: UIViewController {

var selectedTrack: String?

var firstDriver: String?

var secondDriver: String?

var thirdDriver: String?
let  tracks = ["Melbourne", "Manama", "Shanghai", "Baku",
               "Barcelona", "Monaco", "Montreal","Le Castellet","Spielberg",
               "Silverstone","Hockenheim","Budapest","Francorchamps","Monza","Singapore","Sochi","Suzuka","Austin","Interlagos","Abu Dhabi"]
let drivers = ["Lewis Hamilton","Antonio Giovinazzi","Kimi Raikkonen","Charles Leclerc","Sebastian Vettel","Romain Grosjean","Kevin Magnussen","Lando Norris",
               "Carlos Sainz","Valtteri Bottas","Sergio Perez","Lance Stroll","Pierre Gasly","Max Verstappen","Nico Hulkenberg","Daniel Ricciardo","Alexander Albon","Daniil Kvyat","Robert Kubica","George Russell"]
@IBOutlet weak var TrackTextField: UITextField!


@IBOutlet weak var firstTextField: UITextField!

@IBOutlet weak var secondTextField: UITextField!


@IBOutlet weak var thirdTextField: UITextField!


override func viewDidLoad() {
    super.viewDidLoad()


    createTrackPicker()
    createDriverPicker()
    createToolBar()
    // Do any additional setup after loading the view.
}

func createTrackPicker() {
    let trackPicker = UIPickerView()
    trackPicker.tag = 0
    trackPicker.delegate = self
    TrackTextField.inputView = trackPicker
}

func createDriverPicker() {
    let driverPicker = UIPickerView()
    driverPicker.tag = 1
    driverPicker.tag = 2
    driverPicker.tag = 3
    driverPicker.delegate = self
    firstTextField.inputView = driverPicker
    secondTextField.inputView = driverPicker
    thirdTextField.inputView = driverPicker
}

func createToolBar() {

    let toolBar = UIToolbar()
    toolBar.sizeToFit()
    let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(ViewController.dismissKeyboard))
    toolBar.setItems([doneButton], animated: false)
    toolBar.isUserInteractionEnabled = true
    TrackTextField.inputAccessoryView = toolBar
    firstTextField.inputAccessoryView = toolBar
    secondTextField.inputAccessoryView = toolBar
    thirdTextField.inputAccessoryView = toolBar

}
@objc func dismissKeyboard() {
    view.endEditing(true)
}
/*
// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // Get the new view controller using segue.destination.
    // Pass the selected object to the new view controller.
}
 */

}

 extension DriverViewController: UIPickerViewDelegate, UIPickerViewDataSource {
 func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    if pickerView.tag == 0 {
        return tracks.count
    } else {
        return drivers.count
    }
}


func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return 1
}

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    if pickerView.tag == 0 {
        return "\(tracks[row])"
    } else {
        return "\(drivers[row])"
    }
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    if pickerView.tag == 0 {
        selectedTrack = tracks[row]
        TrackTextField.text = selectedTrack
    } else if pickerView.tag == 1 {
        firstDriver = drivers[row]
        firstTextField.text = firstDriver
    } else if pickerView.tag == 2 {
        secondDriver = drivers[row]
        secondTextField.text = secondDriver
    } else if pickerView.tag == 3 {
        thirdDriver = drivers[row]
        thirdTextField.text = thirdDriver
    }
  }
}

This is how it looks on the screen.Simulator Screenshot

rmaddy
  • 314,917
  • 42
  • 532
  • 579
AltBrian
  • 2,392
  • 9
  • 29
  • 58

1 Answers1

1

Look at your function:

func createDriverPicker() {
    let driverPicker = UIPickerView()
    driverPicker.tag = 1
    driverPicker.tag = 2
    driverPicker.tag = 3
    driverPicker.delegate = self
    firstTextField.inputView = driverPicker
    secondTextField.inputView = driverPicker
    thirdTextField.inputView = driverPicker
}

Think about what value the tag property has after this code is run keeping in mind that it can only have one value.

You either need to update the picker view's tag property each time a text field begins editing, or you should abandon the use of the tag and simply check which text field is currently the first responder. See UIPickerView for each text field with different arrays (Swift/Firebase) for an example of how this is done.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • Will have a look at this later. So do advise abandoning the ```tag``` property. – AltBrian Apr 13 '19 at 20:47
  • You either update the picker's tag when each text field begins editing or you update all of the picker view methods to see which text field is currently the first responder. Either works. It's largely a matter of preference. Keep in mind that you should never use a tag value of 0 since that is the default for all views. – rmaddy Apr 13 '19 at 20:49