I've a grid table using a UICollectionView - 4 columns x 4 rows. In the top row, I've three UIPickerViews. If the user selects a new value in the picker, the UILabels in the pickers revert to previous label (columns 1 and 4, not 3), and change the label.text on other pickers.
In columns 1 and 4, while the selection calls the delegate method, the UILabel rolls back to the previous value; and the label of the other picker (col. 1 or 4 - NOT 3) updates to the value selected in the selected picker (without changing the values in the not selected column).
In column 3, the picker appears to work perfectly - delegate called correctly and UILabel remains on the selected value. But if one or both of the labels in columns 1 or 4 have been changed from the default or first value in array, then these labels (in col.s 1 and 4) exchange values (when the picker in col. 3 is changed).
Within a custom UITableViewCell, managing a UICollectionView, I instantiate my custom UICollectionViewCell with a picker in it:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
var cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseI4CVCell, for: indexPath) as! CVCell
switch indexPath.item
{
case 0, 2, 3:
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseI4PickerCVCell, for: indexPath) as! PickerCVCell
cell.caseOfPicker = indexPath.item
cell.reference = self
return cell
class PickerCVCell: UICollectionViewCell, UIPickerViewDelegate, UIPickerViewDataSource
{
var reference: EgPickerDelegate?
var caseOfPicker: Int?
private var fetchedResultsController: NSFetchedResultsController<NSFetchRequestResult>? // controller for fetched results
@IBOutlet weak var pickerInCVCell: UIPickerView!
override func awakeFromNib()
{
super.awakeFromNib()
configureFetchedResultsController()
pickerInCVCell.delegate = self
pickerInCVCell.dataSource = self
}
private func configureFetchedResultsController()
{
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate
else { return }
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Gender")
let sortDescriptor = NSSortDescriptor(key: "sortOrder", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest,
managedObjectContext: appDelegate.persistentContainer.viewContext,
sectionNameKeyPath: nil,
cacheName: nil)
fetchedResultsController?.delegate = self as? NSFetchedResultsControllerDelegate
do { try fetchedResultsController?.performFetch() }
catch { print(error.localizedDescription) }
}
func numberOfComponents(in pickerView: UIPickerView) -> Int
{ return 1 }
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int
{
if let objects = fetchedResultsController?.fetchedObjects
{ return objects.count }
return 4
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView
{
var pickerLabel: UILabel? = (view as? UILabel)
let path = NSIndexPath(item: row, section: 0)
if let gender = fetchedResultsController?.object(at: path as IndexPath) as? Gender
{
let text = gender.text ?? "Text not found"
if pickerLabel == nil
{
pickerLabel = UILabel()
pickerLabel?.textColor = UIColor.black
pickerLabel?.textAlignment = NSTextAlignment.center
pickerLabel?.font = pickerLabel?.font.with( .traitBold, .traitItalic)
}
pickerLabel?.text = text
}
return pickerLabel!
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
{ reference?.myPickerDidSelectRowInCase(selectedRowValue: row, caseOfPicker: caseOfPicker) }
func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat
{ return CGFloat(120.0) }
}
The custom collectionView pickerView didSelectRow delegate method passes the correct caseOfPicker value after selection.
I've tried instantiating cells in different ways - to distinguish them as objects. I've tried using pickerView titleForRow instead of viewForRow, but it behaves the same way. Can't find a helpful dataSource method.