简体   繁体   中英

BEMCheckBox delegate is not called

In my iOS Switch app I have a BEMCheckBox in each table cell. When dequeuing a cell I want to set a delegate that gets called.

My problem is that the checkbox works fine but the delegate is not never called. How to add a delegate to each checkbox?

I want to know which indexPath for checkbox. The plan is to pass model object to the delegate and update it accordingly.

Table cell

let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath)
cell.doneCheckbox.delegate = DoneBEMCheckBoxDelegate()
return cell

Delegate is very simple

class DoneBEMCheckBoxDelegate: NSObject, BEMCheckBoxDelegate {

    @objc func didTap(_ checkBox: BEMCheckBox) {
        print("Checkbox tapped")
    }

}

cell.doneCheckbox.delegate = DoneBEMCheckBoxDelegate() is creating a new DoneBEMCheckBoxDelegate object in a local variable and assigning that as the delegate. Since the delegate property is weak, it will be released as soon as the function exits because there is no strong reference remaining.

I would suggest that having a separate object class to be the delegate probably isn't what you want anyway.

I would set the cell to be the check box delegate and then declare another protocol so that the cell can have its own delegate, which would be your table view controller.

protocol MyCellDelegate {
    func checkBox(for cell: MyCell, isOn: Bool)
}

class MyCell: UITableViewCell, DoneBEMCheckBoxDelegate {

    var delegate: MyCellDelegate?

    override func awakeFromNib() {
        super.awakeFromNib()
        self.doneCheckBox.delegate = self
    }

    @objc func didTap(_ checkBox: BEMCheckBox) {
        print("Checkbox tapped")
        self.delegate?.checkBox(for: self, isOn: checkBox.isOn)
    }

}


class YourViewController: MyCellDelegate {

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        ...
        cell.delegate = self

        return cell
    }

    func checkBox(for cell: MyCell, isOn: Bool) {

        guard let indexPath = tableView.indexPath(for: cell) else {
            return
        }
        // Now do whatever you need to with indexPath
    }
}

This way you avoid creating additional objects and datastructures and you won't have a problem if cells are re-ordered as there is no dependency on index path.

I noticed that delegate is a weak reference in checkbox class, as it is supposed to be :) So my delegate was freed after method scope ended.

I fixed this by storing delegates in view controller during their usage.

var checkboxDelegates: [IndexPath:DoneBEMCheckBoxDelegate] = [:]
...
let checkboxDelegate = DoneBEMCheckBoxDelegate(realm: realm, set: set)
checkboxDelegates[indexPath] = checkboxDelegate
cell.doneCheckbox.delegate = checkboxDelegate

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM