0

I want to use a delegate to make my cells (from a UICollectionView) communicate with my ViewController.

In my Cell.swift file, I am declaring the protocol needed like this (outside the Cell class):

protocol CellDelegate: class {
    func someMethod(param1: String?, param2 param2: Bool)
}

In the same file I am declaring the delegate as follows:

class Cell: UICollectionViewCell {
     weak var delegate: CellDelegate?

     // ... some code ...

     @IBAction func someAction(sender: AnyObject) {
             delegate?.someMethod(param1, param2: true)
     }
}

Now in my ViewController, I am implementing someMethod:

extension ViewController: CellDelegate {
     func someMethod(param1: String?, param2 param2: Bool) {

     // ... some code ...

     }
}

Problem : I can not link the protocol with its implementation, cmd + click in the protocol leads nowhere. In my @IBAction, someMethod is not crashing, but it does nothing.

I saw this topic about the subject, but I do not understand where to implement the Step 6.

Can you help me ?

Thank you for your time.

Community
  • 1
  • 1
BrickDeLait
  • 117
  • 9

1 Answers1

2

You are missing the final step: populating the delegate property of the Cell class. I usually do that in cellForRowAtIndexPath:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = self.table.dequeueReusableCellWithIdentifier("myCellId") as! Cell
    cell.delegate = self
    ...
    return cell
}

Note that there is no magic or automated behavior when using delegates:

  • a delegate is a protocol (your CellDelegate protocol)
  • you implement the protocol in the class you want to respond to the delegate invocations (you did in your ViewController class)
  • you create a delegate property in the class where the delegate methods are invoked (you did in your Cell class)
  • you initialize the delegate property with the actual instance of the class

You just missed the last step, leaving that property uninitialized, so any invocation using optional chaining evaluates to nil (like you did in the someAction method), and nothing happens.

Antonio
  • 71,651
  • 11
  • 148
  • 165
  • On the `cell.delegate = self` part, Xcode tells me that I am assigning the wrong value type. I know that in Objective-C you can set the delegate to `id` to allow it to take any type in consideration. Do you have any idea of how doing it in Swift? – BrickDeLait Jun 17 '15 at 08:15
  • My guess is that the class doesn't implement the delegate protocol - is your `ViewController` implementing `CellDelegate`? – Antonio Jun 17 '15 at 08:36
  • I set an extension on `ViewController`, as you can see on my original question. Maybe it would be better to implement it the classical way? I'll give it a try. – BrickDeLait Jun 17 '15 at 08:54
  • No it should work - I usually implement protocols via extensions. Can you show the actual compiler error message? – Antonio Jun 17 '15 at 09:00
  • Here it is: `Cannot assign a value of type 'GridController' to a value of type 'CellDelegate?'`. I think I got it: I was calling the delegate in a controller which was not implementing `CellDelegate`, as you said before... I was confusing the two controllers. Thank you for your help, now it works ;-) – BrickDeLait Jun 17 '15 at 09:21