Search code examples
iosswiftuitextfieldrealmuipickerview

Swift - how to read data from many UITextFields which generate data by UIPickerView


I have a problem when I tried to read data from my UITextFields.

enter image description here

I have 3 IBOutlets for textFields (Sex, Goal and number of Meals per day). Data for all of that textFields will be displayed by UIPickerView. I Prepared 3 dataSets, different for all textFields. When I tap on 1st textField (Sex) I have PickerView with Data (Male and Female), after that when I click on 2nd textField (Goal) dataSet on UIPickerView wasn't reloaded but, when I tapped on 3rd TextField (number of meals) pickerView data is reloaded with data for 2nd textField. When I choose something from that pickerView 2nd textFieled are setted (after tapping on 3rd textField!). It always work like the same. Any idea?


Solution

  • You can set a pickerView as the textField.inputView.

    The example below is for two text fields sharing a single picker view, but you can extend it easily by checking the identity of the activeTextField in the picker view delegate methods.

    import UIKit
    
    class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
    
        @IBOutlet weak var myTextFieldOne: UITextField!
        @IBOutlet weak var myTextFieldTwo: UITextField!
    
        let pickerDataOne = ["A", "B", "C", "D", "E", "F"]
        let pickerDataTwo = ["1", "2", "3", "4", "5", "6"]
    
        // Holds a reference to current text field
        var activeTextField = UITextField()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            let myPicker = UIPickerView()
            myPicker.delegate = self
            myPicker.dataSource = self
            myTextFieldOne.inputView = myPicker
            myTextFieldTwo.inputView = myPicker
        }
    
        // MARK: UITextField Delegate
    
        func textFieldDidBeginEditing(textField: UITextField!) {
            // Sets tapped textField to active one
            self.activeTextField = textField
            if let picker = self.activeTextField.inputView as? UIPickerView {
                // This is one way to get a reference to the picker view
                picker.reloadAllComponents()
            }
        }
    
        // MARK: UIPickerView Delegate
    
        func numberOfComponents(in pickerView: UIPickerView) -> Int {
            return 1
        }
    
        func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
            // You can have a different data source for each text field
            if activeTextField === myTextFieldOne {
                return pickerDataOne.count
            } else if activeTextField === myTextFieldTwo {
                return pickerDataTwo.count
            }
        }
    
        func pickerView( _ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
            // Gets the title for each row in picker
            if activeTextField === myTextFieldOne {
                return pickerDataOne[row]
            } else if activeTextField === myTextFieldTwo {
                return pickerDataTwo[row]
            }
        }
    
        func pickerView( _ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
            // Populates the text field
            if activeTextField === myTextFieldOne {
               myTextFieldOne.text = pickerDataOne[row]
            } else if activeTextField === myTextFieldTwo {
               myTextFieldTwo.text = pickerDataTwo[row]
            }
        }
    
    }
    

    You can then access the text in any text field by getting myTextFieldOne.text for example.