JOnney
JOnney

Reputation: 89

Use delegate to show/hide a tableview cell

I have a tableview with three rows, In the second row there is UISwitch that when it's off, the third row should be hidden and when it's on, it would be shown.

I use delegate for that: here is the protocol:

protocol ChangeStatusOFSwitchBtnDelegate {
func toggle(isOn: Bool)
}

and here is the configuration of the delegate in UITableViewCell

@IBOutlet weak var deadlineSwitchState: UISwitch!

func configure(swicthIsOn: Bool, delegate: ChangeStatusOFSwitchBtnDelegate) {
    deadlineSwitchState.isOn = swicthIsOn
    self.switchBtnDelegate = delegate
}

@IBAction func changeStateToggle(_ sender: UISwitch) {
    if deadlineSwitchState.isOn == true {
    switchBtnDelegate!.toggle(isOn:true)
    } else {
        switchBtnDelegate!.toggle(isOn:false)
    }
}

var switchBtnDelegate: ChangeStatusOFSwitchBtnDelegate?

and here is some part of the codes in UIViewController

class AddListPopup: UIViewController, UITableViewDelegate, UITableViewDataSource, ChangeStatusOFSwitchBtnDelegate {

// Delegate

private var switchBtnIsOn = false

func toggle(isOn: Bool) {
    self.switchBtnIsOn = isOn
    NewListDetailsTableView.reloadData()
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return (taskCellArray.count - 1 ) + (switchBtnIsOn ? 1 : 0)
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    indexPath.row == 1 {
    let switchCell = tableView.dequeueReusableCell(withIdentifier: "switch cell", for: indexPath) as! NewListPopupViewCell

    switchCell.configure(swicthIsOn: switchBtnIsOn, delegate: self) //Set delegate here

    return switchCell
}
return UITableViewCell()
}

the problem is:

I will get two errors here: first, if I unwrap switchBtnDelegate in UITableViewCell same as the code you see here, I got:

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

this error appears here:

@IBOutlet weak var deadlineSwitchState: UISwitch!

@IBAction func changeStateToggle(_ sender: UISwitch) {
if deadlineSwitchState.isOn == true {
switchBtnDelegate!.toggle(isOn:true) //The error appears here
} else {
    switchBtnDelegate!.toggle(isOn:false)
}
}

var switchBtnDelegate: ChangeStatusOFSwitchBtnDelegate?

and If i use ? to keep it optional:

@IBOutlet weak var deadlineSwitchState: UISwitch!

@IBAction func changeStateToggle(_ sender: UISwitch) {
if deadlineSwitchState.isOn == true {
switchBtnDelegate?.toggle(isOn:true) 
} else {
    switchBtnDelegate?.toggle(isOn:false)
}
}

var switchBtnDelegate: ChangeStatusOFSwitchBtnDelegate?

I got this error:

class AppDelegate: UIResponder, UIApplicationDelegate {   Thread 1: signal SIGABRT

Could anyone help me to where the problem comes from?

Thank you so much

Upvotes: 1

Views: 426

Answers (1)

Mike Hay
Mike Hay

Reputation: 2856

(1)

The reason that your delegate is not being set appears to be that you are missing an if in your code on the first line of tableView(UITableView, cellForRowAt:IndexPath). It looks like that code in the block that you had intended to be an if statement is never running.

I would add an if on that first line and see if it is doing what you wanted.

Update: This would also explain the message unrecognized selector sent to instance 0x7fd3a4068800' in the console, because your method would always return a UITableViewCell, instead of a NewListPopupViewCell.

(2)

Crashing like this

class AppDelegate: UIResponder, UIApplicationDelegate {   Thread 1: signal SIGABRT

usually happens to me when:
1. I'm trying to load a Storyboard that is not part of the target, or
2. I'm trying to use a segue that is not on the controller I'm messaging, or
3. There are missing connections between the controller and other elements in the storyboard.

So, I would make sure that everything in your storyboard (or xib) has the appropriate connections, and try again.

(3)

Regarding the delegate ... You should make sure that your delegates are always declared using the weak keyword, and they are always treated as optional.

weak var delegate: ChangeStatusOFSwitchBtnDelegate?

Upvotes: 1

Related Questions