Search code examples
iostagsuitextfieldswift4uipickerview

how to call 2 different arrays for two different pickerviews (swift4)


My code below features two different textfields ana and sampleTextfield. Right now sampleTextfield works perfectly calling arrray firstHit. But I am trying to figure out how to have ana call and display array secondHit. Right now sampleTextfield is tagged at 1 and ana is tagged at 2. I think tagging is the best way to do this.

    import UIKit

class ViewController: UIViewController,UIPickerViewDelegate, UIPickerViewDataSource {


    let myBUtton = UIButton()

    @IBOutlet var ana : UITextField!
    @IBOutlet var sampleTextField: UITextField!

    var initialc:[NSLayoutConstraint] = []
    var buttonCons:[NSLayoutConstraint] = []
    var textCons:[NSLayoutConstraint] = []
    var textCons2:[NSLayoutConstraint] = []
    var textAna:[NSLayoutConstraint] = []

    var selecteDay : String?



    let firstHit = ["","X","9","8","7","6","5","4","3","2","1","0"]
    let secondHit = ["\\","9","8","7","6","5","4","3","2","1","0"]
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        createToolBar()
        createDayPicker()
        sampleTextField.placeholder = "Enter text here"
        sampleTextField.font = UIFont.systemFont(ofSize: 15)
        sampleTextField.translatesAutoresizingMaskIntoConstraints = false
        sampleTextField.borderStyle = UITextBorderStyle.roundedRect
        sampleTextField.autocorrectionType = UITextAutocorrectionType.no
        sampleTextField.keyboardType = UIKeyboardType.default
        sampleTextField.returnKeyType = UIReturnKeyType.done
        sampleTextField.clearButtonMode = UITextFieldViewMode.whileEditing;
        sampleTextField.contentVerticalAlignment = UIControlContentVerticalAlignment.center

        self.view.addSubview(sampleTextField)

        ana.placeholder = "Enter text here"
        ana.font = UIFont.systemFont(ofSize: 15)
        ana.translatesAutoresizingMaskIntoConstraints = false
        ana.borderStyle = UITextBorderStyle.roundedRect
        ana.autocorrectionType = UITextAutocorrectionType.no
        ana.keyboardType = UIKeyboardType.default
        ana.returnKeyType = UIReturnKeyType.done
        ana.clearButtonMode = UITextFieldViewMode.whileEditing;
        ana.contentVerticalAlignment = UIControlContentVerticalAlignment.center

        self.view.addSubview(ana)
        sampleTextField.translatesAutoresizingMaskIntoConstraints = false
        let leadingc2 = sampleTextField.widthAnchor.constraint(equalToConstant: 80)
        let trailingC2 = sampleTextField.heightAnchor.constraint(equalToConstant: 40)
        let topc2 = sampleTextField.centerXAnchor.constraint(equalTo: self.view.centerXAnchor, constant: -70)
        let bottomc2 = sampleTextField.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: -250)

        textCons = [leadingc2,trailingC2,topc2,bottomc2]




        let leadingc2a = ana.widthAnchor.constraint(equalToConstant: 80)
        let trailingC2a = ana.heightAnchor.constraint(equalToConstant: 40)
        let topc2a = ana.centerXAnchor.constraint(equalTo: self.view.centerXAnchor, constant: 70)
        let bottomc2a = ana.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: -250)

        textAna = [leadingc2a,trailingC2a,topc2a,bottomc2a]

        ana.backgroundColor = .gray
        NSLayoutConstraint.activate(textCons)
        NSLayoutConstraint.activate(textAna)


    }
    func createDayPicker () {
        let dayPicker = UIPickerView()
        dayPicker.tag = 0 
        dayPicker.delegate = self
        dayPicker.backgroundColor = .black
        sampleTextField.inputView = dayPicker

    }


    func createToolBar()  {
        let toolbar = UIToolbar()
        toolbar.sizeToFit()
        let doneButonnt = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(ViewController.cancle))
        toolbar.setItems([doneButonnt], animated: false)
        toolbar.isUserInteractionEnabled = true
        sampleTextField.inputAccessoryView = toolbar
    }

    @objc func cancle() {
        view.endEditing(true)


        if sampleTextField.text == "X"{

            ana.isHidden = true
            sampleTextField.backgroundColor = .red
            NSLayoutConstraint.deactivate(textCons)
            NSLayoutConstraint.deactivate(textAna)



            sampleTextField.translatesAutoresizingMaskIntoConstraints = false
            let leadingc2 = sampleTextField.widthAnchor.constraint(equalToConstant: 80)
            let trailingC2 = sampleTextField.heightAnchor.constraint(equalToConstant: 40)
            let topc2 = sampleTextField.centerXAnchor.constraint(equalTo: self.view.centerXAnchor, constant: -70)
            let bottomc2 = sampleTextField.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: -250)
                   let rightCona = sampleTextField.rightAnchor.constraint(equalTo: self.view.rightAnchor)
                   let leftCona = sampleTextField.leadingAnchor.constraint(equalTo: self.view.leadingAnchor)
            textCons2 = [leadingc2,trailingC2,topc2,bottomc2,rightCona,leftCona]
            NSLayoutConstraint.activate(textCons2)



        }

        else {
            NSLayoutConstraint.deactivate(textCons2)
            ana.isHidden = false

            sampleTextField.translatesAutoresizingMaskIntoConstraints = false
            let leadingc2 = sampleTextField.widthAnchor.constraint(equalToConstant: 80)
            let trailingC2 = sampleTextField.heightAnchor.constraint(equalToConstant: 40)
            let topc2 = sampleTextField.centerXAnchor.constraint(equalTo: self.view.centerXAnchor, constant: -70)
            let bottomc2 = sampleTextField.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: -250)

            textCons = [leadingc2,trailingC2,topc2,bottomc2]




            let leadingc2a = ana.widthAnchor.constraint(equalToConstant: 80)
            let trailingC2a = ana.heightAnchor.constraint(equalToConstant: 40)
            let topc2a = ana.centerXAnchor.constraint(equalTo: self.view.centerXAnchor, constant: 70)
            let bottomc2a = ana.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: -250)

            textAna = [leadingc2a,trailingC2a,topc2a,bottomc2a]

            ana.backgroundColor = .gray
            NSLayoutConstraint.activate(textCons)
            NSLayoutConstraint.activate(textAna)
        }

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


        return 1

    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {

        return firstHit.count
    }
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return firstHit[row]
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {


            selecteDay = firstHit[row]
            sampleTextField.text = selecteDay

    }
    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        var lable: UILabel
        if let view = view as? UILabel {
            lable = view
        } else {
            lable = UILabel()
        }

        lable.textColor = .white
        lable.textAlignment = .center
        lable.font = UIFont(name: "Menlo-Regular", size: 17)
        lable.text = firstHit[row]
        return lable
    }

}

Solution

  • One approach that I can think of is as follow:

        import UIKit
    
    //Indicator to indicate which field is currently active at the moment
    enum ActiveField {
      case ana
      case sample
    }
    
    //protocol that different source will be using or conforms to
    protocol PickerData {
        var source: [String] { get }
        var active: ActiveField { get }
    }
    
    
    //The first source
    struct FirstHit: PickerData {
        var source: [String]
        var active: ActiveField
    }
    
    //The second source
    struct SecondHit: PickerData {
        var source: [String]
        var active: ActiveField
    }
    
    
    
    class ViewController: UIViewController, UITextFieldDelegate {
    
    
    let myBUtton = UIButton()
    
    @IBOutlet var ana : UITextField!
    @IBOutlet var sampleTextField: UITextField!
    
    //These are the actual data received or manually set as the case here
    let firstHit = FirstHit(source: ["","X","9","8","7","6","5","4","3","2","1","0"], active: .ana)
    let secondHit = SecondHit(source: ["\\","9","8","7","6","5","4","3","2","1","0"], active: .sample)
    
    //This one will be used to determine the title displayed in picker view
    var pickerDataSource: PickerData!
    
    //We will use this pickerview for all inputs view
    var dayPicker: UIPickerView!
    
    
    // MARK: - LifeCycle
    override func viewDidLoad() {
        super.viewDidLoad()
    
        //1. create the pickerView
        createDayPicker()
    
        //2. create the toolbar
        createToolBar()
    
        //3. set the pickerview as input to textFields (same pickerview)
        ana.inputView = dayPicker
        sampleTextField.inputView = dayPicker
    
        //4. set the textField delegate so that when they become active we know what source to use
        ana.delegate = self
        sampleTextField.delegate = self
    }
    
    
    func createDayPicker () {
        dayPicker = UIPickerView()
        dayPicker.delegate = self
        dayPicker.dataSource = self
        dayPicker.backgroundColor = .black
    }
    
    
    func createToolBar()  {
        let toolbar = UIToolbar()
        toolbar.sizeToFit()
        let doneButonnt = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(ViewController.cancle))
        toolbar.setItems([doneButonnt], animated: false)
        toolbar.isUserInteractionEnabled = true
        sampleTextField.inputAccessoryView = toolbar
        ana.inputAccessoryView = toolbar
    }
    
    @objc func cancle() {
        view.endEditing(true)
    
        //...Do stuff
    }
    
    
    // MARK: - TextField Delegate
    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
    
        //set the appropriate source
        if textField == ana {
            pickerDataSource = firstHit
        } else if textField == sampleTextField {
            pickerDataSource = secondHit
        }
    
        //reload picker
        dayPicker.reloadAllComponents()
    
        return true
        }
    }
    

    Just separating pickerView delegate and dataSource to extension

    extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource {
    
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1 //since we only have one component to display
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return pickerDataSource.source.count //the count of element inside source
    }
    
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return pickerDataSource.source[row]
    }
    
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        //to know which field is active so that we can identify and set value to that field we are using ActivePicker
        switch pickerDataSource.active {
        case .ana:
            ana.text = pickerDataSource.source[row]
        case .sample:
            sampleTextField.text = pickerDataSource.source[row]
        }
    }
    
    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        var lable: UILabel
        if let view = view as? UILabel {
            lable = view
        } else {
            lable = UILabel()
        }
    
        lable.textColor = .white
        lable.textAlignment = .center
        lable.font = UIFont(name: "Menlo-Regular", size: 17)
        lable.text = pickerDataSource.source[row]
        return lable
    }
    }