I'm trying to get a UIPickerView
inside a custom UITableViewCell
to load. The cell loads fine, and I'm able to pass the data (an array of strings) from the UITableViewController
to the custom cell through a delegate but the picker just loads blank. I can't for the life of me figure out why.
This seems to be a similar issue but the suggested solution (namely to reload the components of the UIPickerView
after setting the pickerData
array in the cellForRowAt
method) doesn't seem to work.
Any help or insights greatly appreciated.
Custom Cell with UIPickerView
class GradeSelectionCell: UITableViewCell, UIPickerViewDataSource, UIPickerViewDelegate, ReusableView {
@IBOutlet var pickerView: UIPickerView!
var pickerData = [String]()
var numComponents = Int()
override func awakeFromNib() {
// Initialization code
self.pickerData = Array<String>()
self.pickerView.delegate = self
self.pickerView.dataSource = self
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return numComponents
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
print(pickerData[row])
return pickerData[row]
}
}
extension GradeSelectionCell: PickerSetupDelegate {
func setupPicker(data: [String], numberOfCompents: Int){
pickerData = data
numComponents = numberOfCompents
print("PickerSetupDelegate Called")
print("pickerData \(String(describing: pickerData))")
}
}
cellForRowAt
let cell = tableView.dequeueReusableCell(withIdentifier: "GradeSelectionCell", for: indexPath) as! GradeSelectionCell
cell.setupPicker(data: grades, numberOfCompents: 1)
// cell.pickerView.reloadAllComponents()
return cell
Registering Cell in viewDidLoad
tableView.register(GradeSelectionCell.self, forCellReuseIdentifier: "GradeSelectionCell")
You're registering the cell using the cell class initializer:
func register(_ cellClass: AnyClass?, forCellReuseIdentifier identifier: String)
But it seems you're trying initialize the cell from a xib. So you should be using the UINib
initializer:
func register(_ nib: UINib?, forCellReuseIdentifier identifier: String)
e.g.
tableView.register(UINib(nibName: "GradeSelectionCell", bundle: nil), forCellReuseIdentifier: "GradeSelectionCell"))
(or whatever the filename of the xib you're using is).
Otherwise, you're just loading an instance of the class directly without the user interface you laid out in the xib.
Note, if you're using a cell defined in a storyboard in your controller's view, then it would already be registered and you do not need to register it again.
And it's not crashing because you're never actually calling the pickerView
property — awakeFromNib
won't be called, and setupPicker
just sets data. Presumably it crashes when you uncomment the line cell.pickerView.reloadAllComponents()
?