Controlling a UIPickerView from an External Class - Using Swift

I cannot find a connection so that the outer class controls the view in the ViewController. I am new to iOS and have spent considerable attention on the solution. A simple example:

Subclass UIPickerView

I am creating a file that is a subclass of UIPickerView and is compatible with the PickerView delegate and data source.

class MyPickerView: UIPickerView, UIPickerViewDelegate, UIPickerViewDataSource { //In here I conform to all the required methods...no problems there } 

Main view controller with output for PickerView

In my MainViewController, I create an output for my selection. Also, in StoryBoard, I plug in a โ€œcustom classโ€ for my Picker View for MyPickerView above.

 class MainViewController: UIViewController { @IBOutlet weak var myPickerView: UIPickerView! override func viewDidLoad() { //how do I hookup my picker view class } } 

My questions:

  • How do I tell my MainViewController that my subclass "MyPickerView" controls the selection view for it?

  • How to enable communication between subclass and view controller?

---------------------

UPDATE: FINAL DECISION Enabling @Oscar Response

The @scscar suggestion below was great. To clarify, I would like my PickerView subclass to be a UIPickerView delegate, because Picker will always have the same interface and there are many PickerView delegate methods for the user interface. (attribitedTitleForRow, widthForComponent, rowHeightForComponent, etc.) I do not want to name these delegate methods in every ViewController that this PickerView uses.

Now that the PickerView "didSelectRow" is called, we need to notify our ViewController and pass the value that was selected. To make this work, I used a protocol. (summarized below). This topic took me some time to find out, but is crucial, so I suggest spending time with the protocols and delegation, if that makes no sense.

  • Create a protocol in PickerView using the func function that will be used to view the ViewControllers that represent this PickerView:

     protocol MyPickerViewProtocol { func myPickerDidSelectRow(selectedRowValue:Int?) } 
  • In the ViewController representing PickerView, it matches your PickerView protocol. In doing so, you need to place the func myPickerDidSelectRow somewhere in your ViewController:

     class MyViewController: MyPickerViewProtocol { func myPickerDidSelectRow(selectedRowValue:Int?) { //do stuff to update your ViewController } } 
  • @ Oscar's answer below will connect the picker view to your view controller, but there is one more thing. In order for PickerView to speak, you will need a property in your PickerView, which is a reference to the view controller in which it is contained. Here's the PickeView and ViewController classes in perspective:

     //PickerView Subclass ------------------ protocol MyPickerViewProtocol { func myPickerDidSelectRow(selectedRowValue:Int?) } class MyPickerView: UIPickerView { //Note: this var is of type your Picker protocol above. Because the ViewController will conform to the protocol, this var will be the reference (or the pointer) to the protocol func you implement in your ViewController...which is myPickerDidSelectRow var propertyThatReferencesThisViewController:MyPickerViewProtocol? } //ViewController Class ---------------- myPicker = MyPickerView() myPickerView.dataSource = myPicker //note: myPickerView is the outlet of type UIPickerView in your ViewController myPickerView.delegate = myPicker //HERE THE PROPERTY from our PickerView subclass that will point to this ViewController protocol methods that we implemented. From the MyPickerViewProtocol myPicker.propertyThatReferencesThisViewController = self 
  • Now that the row is selected in our PickerView, tell ViewController using our property: propertyThatReferencesThisViewController

     class MyPickerView: UIPickerView { //This Property points to the ViewController conforming to the protocol. This property will only be able to access the stuff you put in the protocol. It won't access everything in your ViewController var propertyThatReferencesThisViewController:MyPickerViewProtocol? //didSelectRow UIPickerView Delegate method that apple gives us func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { //get your picker values that you need let theRowValue = someArray[row] propertyThatReferencesThisViewController?.myPickerDidSelectRow(theRowValue) //the ViewController func will be called passing the row value along } } 
+5
source share
2 answers

Subclass Pickerview

 class MyPickerView: UIPickerView, UIPickerViewDataSource, UIPickerViewDelegate { var oficinas = ["oficina 1", "Oficinas 2", "Oficina 3"] func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return oficinas.count } func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int { return 1 } func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { return oficinas[row] } } 

Main view controller with output for PickerView

 class MainViewController: UIViewController { @IBOutlet weak var myPickerView: UIPickerView! var pickerOficinas: MyPickerView! override func viewDidLoad() { //how do I hookup my picker view class pickerOficinas = MyPickerView() myPickerView.delegate = pickerOficinas myPickerView.dataSource = pickerOficinas } } 
+7
source

I think you may have grabbed the wrong end of the stick!

Why do you want to make the collector your delegate? The fact is that the delegate can indicate to his delegate what was chosen, etc.

I would think that what you should do is make your UIPickerViewDelegate conformance view controller and make it a collector delegate and put the logic on everything you want when an element is selected in these delegate methods. I see no other way to โ€œtellโ€ your view controller about the collector.

In addition, if you reference your weak collector, then if you do not keep the strong link to it somewhere else (for example, this is part of the presentation hierarchy), it will be released.

+1
source

All Articles