Search code examples
iosswiftxibviewcontrolleruipicker

How to pass values out of reusable PickerView.xib in swift


I created a reusable UIPickerView:

enter image description here

PickerView.swift:

class PickerView: UIView, UIPickerViewDelegate, UIPickerViewDataSource {

    @IBOutlet weak var pickerView: UIPickerView!

    var labels: [String] = [] {
        didSet {
            self.pickerView.reloadAllComponents()
        }
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        Bundle.main.loadNibNamed("PickerView", owner: self, options: nil)
        self.addSubview(pickerView)
    }

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

This code makes it so that I can initialize a UIPickerView just by setting the class of a UIView to PickerView:

enter image description here

And to add data to the UIPickerView, I just create an outlet and add data via the outlet. So, my ViewController.swift file looks like this:

ViewController.swift:

class ViewController: UIViewController {

    @IBOutlet weak var pickerView: PickerView!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.pickerView.labels = ["Label1","Label2","Label3"]
    }
}

Here's my question: How can I pass the didSelectRow value out of the picker to use in ViewController.swift?


Solution

  • create custom protocol

    protocol MyPickerDelegate: NSObjectProtocol {
        func didSelectSomething(some: String)
    }
    

    create instance inside PickerView.swift like

    weak var myDelegate: MyPickerDelegate?
    

    then in viewDidLoad

    self.pickerView.myDelegate = self
    

    then make your UIViewController conform protocol

    extension ViewController: MyPickerDelegate {
        func didSelectSomething(some: String) {
           // self.doStuff()
        }
    }
    

    then inside PickerView.swift call didSelectRow and inside it

    self.myDelegate?.didSelectSomething(some: "SomeValue")