iosswiftuipickerviewuipickerviewdatasourceuipickerviewdelegate

How to return selected value in UIPickerDelegate when created programatically


I have a viewController that has a bunch of inputs on it. Some of them are normal text but some require input from a picker. I decided to move the implementation of each PickerDelegate and PickerDataSource into a separate file to keep things a little cleaner. The data is appearing but on select of the Picker I don't know how to get the event to fire in my viewController. Currently it only fires in the PickerDelete class.

Some basic layout information is

class MyClass: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

let jobTypePickerValues = ["value1", "value2"]

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

// returns the # of rows in each component..
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    return jobTypePickerValues.count
}

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

func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
{
    //println("I want this in the view controller that set up the picker")
}

In my view controller which is showing the picker I have the following

    override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.


    myClassSource = MyClass()
    pickerView = UIPickerView()
    pickerView.dataSource = myClassSource
    pickerView.delegate = myClassSource

    // set the input view of the job type to be a picker view
    textInput.inputView = pickerView
    textInput.text = jobTypePickerValues[0]
}

Solution

  • You need to create one custom delegate and implement in the ViewController where you are creating pickerView.

    protocol CustomPickerDelegate {
         func selectedItem(item: String)
    } 
    

    Now create instance of this protocol inside MyClass and implement inside the `ViewController``

    class MyClass: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
    
        let jobTypePickerValues = ["value1", "value2"]
        var delegate: CustomPickerDelegate?
        .. Other code and methods
    
        func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
             delegate?. selectedItem(jobTypePickerValues[row])
        }
    }
    

    Now set the delegate in viewDidLoad and implement the method of protocol.

    class ViewController: UIViewController, CustomPickerDelegate {
    
         override func viewDidLoad() {
             super.viewDidLoad()
    
             myClassSource = MyClass()
             myClassSource.delegate = self
             pickerView = UIPickerView()
             pickerView.dataSource = myClassSource
             pickerView.delegate = myClassSource
    
             // set the input view of the job type to be a picker view
             textInput.inputView = pickerView
             textInput.text = jobTypePickerValues[0]
         }
    
          func selectedItem(item: String) {
    
              textInput.text = item
          }
    }