PickerView in a Table Cell

I'm trying to use a pickerView in a TableCell; I was able to use it in a simple view, but when I replicate in a table cell the iOS simulator abort(signal SIGABRT) with the following message:

2018-06-06 07:13:50.747379+0200 pickerCell[2558:118616] -[pickerCell.TableViewController numberOfComponentsInPickerView:]: unrecognized selector sent to instance 0x7ffb15609df0

2018-06-06 07:13:50.752810+0200 pickerCell[2558:118616] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[pickerCell.TableViewController numberOfComponentsInPickerView:]: unrecognized selector sent to instance 0x7ffb15609df0'

What I'm missing?

Thanks.

Accepted Reply

Great. So no need to declare delegate in IB.


To connect in IB, you should control-drag from the name of the picker in the objects list (on the left of the drawing panel) up to the cellController ; Hope it works here. Otherwise, doing in code is OK.


Don't forget to close this thread once OK.

Replies

Have you defined a custom pickerView, or is it a datePicker for instance ?


If custom, can you post the code where you define the custom picker ?

As well as where you call (if you call) numberOfComponentsInPickerView


The 2 datasource functions to implements are defined as :


func numberOfComponents(in: UIPickerView) -> Int

Called by the picker view when it needs the number of components.


func pickerView(UIPickerView, numberOfRowsInComponent: Int) -> Int

Called by the picker view when it needs the number of rows for a specified component.


Seems that numberOfComponentsInPickerView has been obsoleted and replaced by numberOfComponents(in: UIPickerView)

The code is very simple, actually it is a test case to be completed.

I connected the pickerView dataSource and delegate to the tableViewController on the graphic interface


The sequence of function call is:

numberOfSections

tableView(_ tableView: UITableView, numberOfRowsInSection)

tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)

awakeFromNib()


The message "unrecognized selector sent to instance <id>" have the id of the TableViewController.


class TableViewController: UITableViewController 
     ....
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cella", for: indexPath)
        return cell
    }

===============================================================
class TableViewCell: UITableViewCell, UIPickerViewDelegate, UIPickerViewDataSource
{
  func numberOfComponents(in pickerView: UIPickerView) -> Int {
  return 2
  }
  func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
  return 5
  }
  func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
  return "cucu"
  }
  @IBOutlet weak var picker: UIPickerView!
  override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
}
class TableViewController: UITableViewController {
     ....
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cella", for: indexPath)
        return cell
    }

===============================================================
class TableViewCell: UITableViewCell, UIPickerViewDelegate, UIPickerViewDataSource
{
  func numberOfComponents(in pickerView: UIPickerView) -> Int {
  return 2
  }
  func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
  return 5
  }
  func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
  return "cucu"
  }
  @IBOutlet weak var picker: UIPickerView!
  override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
}

Did you set the delegate and dataSource for the picker (in IB) ? I do not see it in code.

Yes. I set both the delegate and the dataSource for the picker in Interface Builder

Did you set them to the TableViewCell (not the Table View, because picker delegation is defined in the cell) ? Does the picker draw correctly ?

IB didn't allow me to connect the pickerView to the cell toset delegate and dataSource; I conected them to the tableView.

Now I add the setting in the cell and it works:

override func awakeFromNib() {

super.awakeFromNib()

picker.dataSource = self

picker.delegate = self

}


Thank you Claude for helping me understand.

Do you know how to set pickerView delegate and dataSource in the IB, so to have a deeper comprehension?

Great. So no need to declare delegate in IB.


To connect in IB, you should control-drag from the name of the picker in the objects list (on the left of the drawing panel) up to the cellController ; Hope it works here. Otherwise, doing in code is OK.


Don't forget to close this thread once OK.

Thanks Claude.
Xcode 9.4:

Control drag do not work toward the cell, but I just found these sequence:

  • right click on the picker on the object list => a pop up with the picker name appears
  • drag from the Outlet/dataSource (in the pop up) to the cell in the object list
  • repeat for the delegate

Otherwise the programmatic solution in the func awakeFromNib works.