Cell Delegate Method Not Being Called

I have set up a collection view cell programmatically which I am registering in the cell registration of a diffable data source. I have set up a delegate for the cell, and the view controller which contains the collection view as the delegate for the cell. However, calling the cell delegate method from the cell is not calling the method in the view controller.

This is my code:

`// in my view controller: cell.delegate = self

// in my collection view cell: delegate?.repromptLLMForIconName(iconName, index: index, emotion: emotion, red: red, green: green, blue: blue)

`

But although the delegate method in the collection view gets called, my method implementation in the view controller does not. What could possibly be going wrong?

However, calling the cell delegate method from the cell is not calling the method in the view controller.

It's not very clear.

 

calling the cell delegate method from the cell

Which method is it ? repromptLLMForIconName ?

 

is not calling the method in the view controller.

Which method is it ?

Have you checked that delegate is not nil ?

print("delegate", delegate)
delegate?.repromptLLMForIconName(iconName, index: index, emotion: emotion, red: red, green: green, blue: blue)

Thanks @Claude31 , per your comments, I have a function which is called repromtLLMForIconName which is in my EmotionExplorerCellDelegate protocol. When I call the method which is repromtLLMForIconName from my cell, this method is not called in my delegate which is my EmotionExplorerViewController. I have not checked that the delegate is not nil.

Upon checking if the delegate is nil, the delegate is not nil. However, when I reattempted to run the app I ran into this issue:

I am registering the cell using UICollectionView.CellRegistration in my view controller class and assigning cell.delegate = self inside this registration completion handler. My cell has a var delegate: EmotionExplorerCellDelegate? property, and inside the configure(iconName: String, title: String, red: CGFloat, green: CGFloat, blue: CGFloat) method in the cell is where I am calling delegate?.repromptLLMforIconName. Now it appears that my cell is nil inside my cell registration.

Firstly, I would recommend making the delegate property in your cell weak to avoid retain cycles.

weak var delegate: EmotionExplorerCellDelegate?

Whether that's the cause of the issue or not, I don't know.


Without you providing more code of the surrounding context, it will be difficult to figure out a solution. For example, how is the delegate defined, what does the custom cell and the configure method look like, are there any other things to note about the cell registration and data source — just to examine if there are any other potential causes, because there aren't any immediate issues visible.

When looking at code in documentation, registration is done differently, by creating a default content configuration and then adjusting:

let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, Int> { cell, indexPath, item in
    
    var contentConfiguration = cell.defaultContentConfiguration()
    
    contentConfiguration.text = "\(item)"
    contentConfiguration.textProperties.color = .lightGray
    
    cell.contentConfiguration = contentConfiguration
}

Could you also test with a log:

let mainCellRegistration = UICollectionView.CellRegistration<EmotionExplorerCell, Item> { cell, indexPath, item in
  print("cell", cell, indexPath, item) // <<-- ADD THIS
  switch item {
    case .main(emotion: let emotion, icon: let iconName, red: let red, green: let green, blue: let blue) :
      cell.configure(iconName: iconName, title: emotion, red: red, green: green, blue: blue)
      cell.index = indexPath.row
      cell.delegate = self
  case .title(title: -, buttonTitle:

This is my code:

// UI View Controller Class

class EmotionExplorerViewController: UIViewController, UINavigationControllerDelegate {
       func configureDataSource() {
        // Cell registration for main section
        let mainCellRegistration = UICollectionView.CellRegistration<EmotionExplorerCell, Item> { cell, indexPath,
            item in
            switch item {
                case .main(emotion: let emotion, icon: let iconName, red: let red, green: let green, blue: let blue):
                    cell.delegate = self
                    cell.index = indexPath.row
                    print("collection view cell,", cell)
                    cell.configure(iconName: iconName, title: emotion, red: red, green: green, blue: blue)
                case .title(title: _, buttonTitle: _):
                    break
                case .filter(name: _):
                    break
                case .skeleton: break
            }
        }
}

// Delegate method implementation
extension EmotionExplorerViewController: EmotionExplorerCellDelegate {
    func repromptLLMForIconName(_ iconName: String, index: Int, emotion: String, red: CGFloat, green: CGFloat, blue: CGFloat) {
        
        guard let numberOfTries = geminiResponse?.numberOfTries, numberOfTries < 3 else { return }
        
        geminiResponse?.rempromptForIconName(iconName) { [self] emotions, error in
            
            if var item = dataSource.itemIdentifier(for: IndexPath(row: index, section: 3)) {
                
                var snapshot = dataSource.snapshot(for: .main)
                
                if let newEmotion = emotions?.first {
                    
                    var insertItem = Item.main(emotion: emotion, icon: newEmotion.sfSymbolName, red: red, green: green, blue: blue)
                    
                    snapshot.insert([insertItem], after: item)
                    
                    snapshot.delete([item])
                    
                    dataSource.apply(snapshot, to: .main, animatingDifferences: true)
                }
            }
        }
    }
}

// UI Collection View Cell Class 

protocol EmotionExplorerCellDelegate {
    func repromptLLMForIconName(_ iconName: String, index: Int, emotion: String, red: CGFloat, green: CGFloat, blue: CGFloat)
}

class EmotionExplorerCell: UICollectionViewCell {
    
    var delegate: EmotionExplorerCellDelegate?
    
    var iconImageView: UIImageView!
        
    var titleLabel: UILabel!
        
    var index: Int!
    
    var emotion: String!
    
    var red: CGFloat!
    
    var green: CGFloat!
    
    var blue: CGFloat!
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        configureCell()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func prepareForReuse() {
        super.prepareForReuse()
        iconImageView.image = nil
        titleLabel.text = nil
        contentView.backgroundColor = nil
    }
    
    private func configureCell() {
        
        iconImageView = UIImageView()
        iconImageView.contentMode = .scaleAspectFit
        iconImageView.tintColor = .black
        iconImageView.translatesAutoresizingMaskIntoConstraints = false
        
        titleLabel = UILabel()
        titleLabel.font = .systemFont(ofSize: 18, weight: .medium)
        titleLabel.textColor = .black
        titleLabel.translatesAutoresizingMaskIntoConstraints = false
        
        contentView.layer.cornerRadius = 7
        contentView.layer.cornerCurve = .continuous
        contentView.clipsToBounds = true
        
        contentView.addSubview(iconImageView)
        contentView.addSubview(titleLabel)

        NSLayoutConstraint.activate([
            iconImageView.centerXAnchor
                .constraint(equalTo: contentView.leadingAnchor, constant: 20),
            iconImageView.centerYAnchor
                .constraint(equalTo: contentView.centerYAnchor),
            
            titleLabel.leadingAnchor
                .constraint(equalTo: iconImageView.centerXAnchor, constant: 20),
            titleLabel.centerYAnchor
                .constraint(equalTo: contentView.centerYAnchor),
            titleLabel.trailingAnchor
                .constraint(lessThanOrEqualTo: contentView.trailingAnchor, constant: -16)
        ])
    }
    
    func configure(iconName: String, title: String, red: CGFloat, green: CGFloat, blue: CGFloat) {
        
        if let image = UIImage(systemName: iconName) {
            iconImageView.image = image
        } else {
            print("delegate", delegate)
            delegate?.repromptLLMForIconName(iconName, index: index, emotion: emotion, red: red, green: green, blue: blue)
        }
         
        iconImageView.image = UIImage(systemName: iconName)
        titleLabel.text = title.capitalized
        
        let transformer = UIConfigurationColorTransformer.init { color in
            color.withProminence(.quaternary).withAlphaComponent(0.6)
        }
        
        let color = UIColor(
            red: red/255,
            green: green/255,
            blue: blue/255,
            alpha: 1
        )
        
        contentView.backgroundColor = transformer.callAsFunction(color)
    }
}

Where is configureDataSource called ?

Cell Delegate Method Not Being Called
 
 
Q