Search code examples
iosswiftuipickerview

Why I can't select my first data in the picker view list?


So I have a button in the view controller, and if I tap that label, it will show a pop up which is actually a picker view.

I will show the picker view pop up by using present modally, using the code below

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let popup = storyboard.instantiateViewController(withIdentifier: "dataPickerPopup") as! DataPickerPopUpVC
popup.delegate = self
popup.selectionList = ["R16G","R22G"]
popup.titlePopup = "UNITS"
popup.startingData = availableUnits[0]
present(popup, animated: true, completion: nil)

The picker view pop up will be look like this : enter image description here

The code I use in the popupVC is like this :

import UIKit


protocol DataPickerPopupDelegate {
    func selectedValueFromPopUp (data: String)
}



class DataPickerPopUpVC: UIViewController {

    @IBOutlet weak var titlePopupLabel: UILabel!
    @IBOutlet weak var pickerView: UIPickerView!
    @IBOutlet weak var saveButton: UIButton!

    var selectionList : [String]!
    var pickedData = ""
    var startingData = ""
    var titlePopup = ""

    var delegate : DataPickerPopupDelegate?



    override func viewDidLoad() {
        super.viewDidLoad()

        pickerView.delegate = self
        setPickerViewStartingPosition()
        titlePopupLabel.text = titlePopup

    }


    @IBAction func saveButtonDidPressed(_ sender: Any) {

        // picked data will be sent to caller VC using protocol delegate pattern.

        delegate?.selectedValueFromPopUp(data: pickedData)
        dismiss(animated: true, completion: nil)
    }


    @IBAction func closeReusablePopup(_ sender: Any) {
        dismiss(animated: true, completion: nil)
    }




}

extension DataPickerPopUpVC {
    // MARK: - Helper Methods

    func setPickerViewStartingPosition() {
        let index = selectionList.index(of: startingData)
        pickerView.selectRow(index ?? 0, inComponent: 0, animated: false)
    }
}



// MARK: - Picker View Delegate & Data Source
extension DataPickerPopUpVC : UIPickerViewDelegate, UIPickerViewDataSource {

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

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return selectionList.count
    }


    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        pickedData = selectionList[row]
    }


    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        let pickerLabel = UILabel()
        if UIDevice.current.userInterfaceIdiom == .pad {
            pickerLabel.font = UIFont.systemFont(ofSize: 40)
            pickerLabel.text = selectionList[row]
            pickerLabel.textAlignment = .center
        } else if UIDevice.current.userInterfaceIdiom == .phone {
            pickerLabel.font = UIFont.systemFont(ofSize: 25)
            pickerLabel.text = selectionList[row]
            pickerLabel.textAlignment = .center
        }
        return pickerLabel
    }



}

After the user press 'Choose' button, it will send the selected units back to the caller VC using delegate pattern.

But I have something wrong in here. As you can see, the starting position of the picker view will always be "R16G". If I directly press the 'choose' button after the picker view pop up shows up, it seems it will always give me an empty string of selected data. It seems that the didSelectRow is not triggered.

But if I scroll down from "R16G" to "R22G" and then press 'choose' button, it will give string "R22G". I have no issue if i choose R22G.

And if I scroll down from "R16G" to "R22G" and then back again to "R16G" and then press 'choose' button, it will give me the string "R16G", it works as I expected.

It seems the first list of the picker view doesn't give a string value back to me if I don't scroll down first.

Here is the .gif file of my problem : http://g.recordit.co/fRnvVJ2hi0.gif

How could I fix this? Thanks in advance :)


Solution

  • You can store the first value of array as selected and in didSelect you can update that variable with current value.

    So in viewDidLoad() add these lines :

    if !selectionList.isEmpty {
       pickedData = selectionList[0]
    }