Search code examples
swiftxcodetableviewrownsuserdefaults

Save the select state of a button in UITableView row (Swift)


I have a button called btnChk2 on a UITableview row. When the user press the btnChk2 that the button btnChk get selected. The code above works to make that happen but when I quit the app and open it back up the status of the checkbox is the not the same, what I want for example is that if a row checkbox is selected, I want when the user leaves the app and comeback the same checkbox stay selected, tried it with NSUserDefaults but didn't worked with me.

Here is the code that works but it doesn't save the state of the checkbox:

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

    let cell = tableView.dequeueReusableCell(withIdentifier: "CheckBoxCell")
    if let lbl = cell?.contentView.viewWithTag(1) as? UILabel {
        lbl.text = "item-\(1)"
    }

    if let btnChk = cell?.contentView.viewWithTag(2) as? UIButton {
        btnChk.addTarget(self, action: #selector(checkboxClicked(_ :)), for: .touchUpInside)
    }

    if let btnChk2 = cell?.contentView.viewWithTag(100) as? UIButton {
        btnChk2.addTarget(self, action: #selector(checkboxClicked(_ :)), for: .touchUpInside)
    }
    return cell!
}

@objc func checkboxClicked(_ sender: UIButton) {

    guard let cell = sender.superview?.superview as? UITableViewCell else {
        return
    }

    if  sender.tag == 2 {

        if let btnChk2 = cell.contentView.viewWithTag(100) as? UIButton {
            if btnChk2.isSelected == true {
                btnChk2.isSelected = false
            }else{
                btnChk2.isSelected = true
            }
        }
        sender.isSelected = false
    }else if sender.tag == 100{
        if let btnChk = cell.contentView.viewWithTag(2) as? UIButton {
            if btnChk.isSelected == true {
                btnChk.isSelected = false

            }else{
                btnChk.isSelected = true
            }
        }
    }
}

Solution

  • Good suggestion don't use userdefault for this purpose, user default only use for user setting purpose, It's best to use core data or save in plist file. anyway here is solution using UserDefaults.

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        var cell : UITableViewCell!
        // code to check for a particular tableView to display the data .
        if tableView == ScheduleTableView{
    
    
    
            cell = tableView.dequeueReusableCell(withIdentifier: "ScheduleCell", for: indexPath as IndexPath)
            let lblCity = cell.viewWithTag(1)as! UILabel
            lblCity.text = ScheduleArray[indexPath.row] as String
    
            if let btnChk2 = cell?.contentView.viewWithTag(100) as? UIButton {
                btnChk2.addTarget(self, action: #selector(checkboxClicked(_ :)), for: .touchUpInside)
            }
    
            if let btnChk2 = cell.contentView.viewWithTag(22) as? UIButton {
    
                btnChk2.isSelected = (UserDefaults.standard.integer(forKey: String(format: "indexpath%d", (indexPath.row))) == indexPath.row) ? true : false
            }  
        }
        if tableView == GoalsTableView{
            cell = tableView.dequeueReusableCell(withIdentifier: "GoalsCell", for: indexPath as IndexPath)
            let lbl3 = cell.viewWithTag(2)as! UILabel
            lbl3.text = GoalsArray[indexPath.row]as? String
        }
        return cell
    }
    
    
    @objc func checkboxClicked(_ sender: UIButton) {
        print("AAAA")
    
        // sender.isSelected = !sender.isSelected
    
    
        guard let cell = sender.superview?.superview as? UITableViewCell else {
            return
        }
    
        let buttonPosition:CGPoint = sender.convert(CGPoint.zero, to:self.ScheduleTableView)
        let indexPath = self.ScheduleTableView.indexPathForRow(at: buttonPosition)
    
        if  sender.tag == 100 {
    
            if let btnChk2 = cell.contentView.viewWithTag(22) as? UIButton {
                if btnChk2.isSelected == true {
                    btnChk2.isSelected = false
                    UserDefaults.standard.set(-1, forKey: String(format: "indexpath%d", (indexPath?.row)!))
    
                }else{
                    btnChk2.isSelected = true
                    UserDefaults.standard.set(indexPath?.row, forKey: String(format: "indexpath%d", (indexPath?.row)!))
                }
            }
            sender.isSelected = false
        }
    
    
    }