Reputation: 655
I'm trying to make a protocol and a delegate in Swift but i'm having some issues. I want to have a switch button in the cells of a Table View. Here is my protocol:
import Foundation
import UIKit
protocol CellProtocol {
func onSwitchToogle (sender : AnyObject , onCell : UITableViewCell)
}
Here is my cell class:
import UIKit
class Cell: UITableViewCell {
@IBOutlet weak var label: UILabel!
@IBOutlet weak var flag: UISwitch!
var cellDelegate:CellProtocol!
@IBAction func Toogle(sender: AnyObject) {
if((cellDelegate?.onSwitchToogle(sender, onCell: self)) != nil){
}
}
}
And here is my ViewController:
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, CellProtocol {
func onSwitchToogle(sender: AnyObject, onCell: UITableViewCell) {
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! Cell
cell.label.text = "sadsad"
return cell
}
}
The problem is: it never enters in the if condition in the IBAction of my switch and it never enters in the method on the ViewController.
Upvotes: 2
Views: 141
Reputation: 437432
A couple of things:
You want to make sure that you specify the delegate in cellForRowAtIndexPath
:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! Cell
cell.cellDelegate = self
cell.label.text = "sadsad"
return cell
}
Make sure you don't have a strong reference cycle by making the cellDelegate
property weak
:
weak var cellDelegate: CellProtocol!
To allow you to have weak references to the protocol type, you must make the protocol a class
protocol:
protocol CellProtocol : class {
func onSwitchToggle (sender : AnyObject, onCell : UITableViewCell)
}
You obviously just want to call onSwitchToggle
if the delegate is set (using optional chaining):
@IBAction func toggle(sender: AnyObject) {
cellDelegate?.onSwitchToggle(sender, onCell: self)
}
No test is required to make sure the delegate implemented the method, because if the view controller conforms to the protocol, it must implement that method.
Please forgive me, but I changed a method names (toggle vs toogle, start methods names with lowercase letters, etc.), but hopefully this illustrates the key points.
Upvotes: 1
Reputation: 25459
In cellForRowAtIndexPath set up the delegate to self:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! Cell
cell.label.text = "sadsad"
cell.cellDelegate = self
return cell
}
Upvotes: 0