I created a custom cell
and a protocol
to be aware of the changes on the UISwitch
. I think i have everything i need but i can't get the func didChangeSwitchState
to be triggered.
VouchersViewController.swift
// MARK: - UITableViewDelegate
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:VouchersFilterCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! VouchersFilterCell
cell.delegate = self
cell.textLabel?.text = self.vouchersFilters[indexPath.row]
return cell
}
// MARK: - VouchersFilterCellDelegate
func didChangeSwitchState(sender: VouchersFilterCell, isOn: Bool) {
let indexPath = self.tableView.indexPath(for: sender)
debugPrint(indexPath?.row)
}
BaseCell.swift
class BaseCell: UITableViewCell {
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
// code common to all your cells goes here
setupViews()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func setupViews(){
}
}
VouchersFilterCell.swift
protocol VouchersFilterCellDelegate: class {
func didChangeSwitchState(sender: VouchersFilterCell, isOn: Bool)
}
class VouchersFilterCell: BaseCell {
// MARK: - UIComponent
let titleLabel = UILabel()
let filterSwitch: UISwitch = {
let fSwitch = UISwitch()
fSwitch.addTarget(self, action: #selector(handledSwitchChange(sender:)), for: .valueChanged)
return fSwitch
}()
weak var delegate: VouchersFilterCellDelegate?
// MARK: - Life Cycle
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
// MARK: - Setup
override func setupViews() {
addSubview(titleLabel)
addSubview(filterSwitch)
addConstraintsWithFormat(format: "V:|-13-[v0]-13-|", views: titleLabel)
addConstraintsWithFormat(format: "H:|-16-[v0]-16-[v1]-16-|", views: titleLabel, filterSwitch)
addConstraintsWithFormat(format: "V:|-7-[v0]", views: filterSwitch)
}
// MARK: - IBAction
@IBAction func handledSwitchChange(sender: UISwitch) {
self.delegate?.didChangeSwitchState(sender: self, isOn:filterSwitch.isOn)
}
}
As we figured out together in the comments it seems like a let property is created before self is ready so the Switch target is nil. Changing to a lazy var ensures self is created first.
lazy var filterSwitch: UISwitch = {
let fSwitch = UISwitch()
fSwitch.addTarget(self, action: #selector(handledSwitchChange(sender:)), for: .valueChanged)
return fSwitch
}()