删除行时 UITableView 中的复选框不起作用

Checkbox in UITableView not working when row is deleted

I have implemented a checkbox in UITableView controller, it works perfectly but when the checkbox are selected and the rows in the tableview are deleted and the when I add a new row to the tableview it gets selected. 这是我项目的 link:https://files.fm/f/tepkz2du 我觉得跟删除某行时,索引路径乱了有关。

更新代码:

cellForRowAt:

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

if let btnChk2 = cell.contentView.viewWithTag(22) as? UIButton {
        btnChk2.isSelected = UserDefaults.standard.integer(forKey: myarray[indexPath.row]) == (indexPath.row + index) ? true : false
    }

复选框已点击

    let defaults = UserDefaults.standard
    let myarray = defaults.stringArray(forKey: "ScheduleArray") ?? [String]()
    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: myarray[(indexPath?.row)!] )
                UserDefaults.standard.synchronize()

            }else{
                btnChk2.isSelected = true
                UserDefaults.standard.set((indexPath?.row)! + index, forKey: myarray[(indexPath?.row)!])
                UserDefaults.standard.synchronize()
            }
        }
        sender.isSelected = false
    }

editingStyle == .delete:

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

    if editingStyle == .delete {

    if tableView == ScheduleTableView{


        let defaults = UserDefaults.standard
        var myarray = defaults.stringArray(forKey: "ScheduleArray") ?? [String]()
        print(myarray)
        myarray.remove(at: indexPath.row)
        defaults.set(myarray, forKey: "ScheduleArray")
        ScheduleTableView.deleteRows(at: [indexPath], with: .fade)


    }
 }

您可以在 UITableViewCell 中使用 func prepareForReuse() 方法来确保在插入新行时取消选中该复选框。

您根据其索引路径将选中按钮的值存储在 userdefaults 中。这种态度的问题是当你删除单元格时,新单元格正在获取错误的前一个单元格的索引路径。

您应该使用一个模型来表示您的行。在 "ScheduleArray" 中存储一个对象,而不仅仅是一个字符串。

类似的东西:

struct myRow {
    var title: String = ""
    var isSelected: Bool = false
}
if let btnChk2 = cell.contentView.viewWithTag(22) as? UIButton {
            btnChk2.isSelected = UserDefaults.standard.integer(forKey: myarray[indexPath.row]) == (indexPath.row + index) ? true : false
        }

更改 cellForRowAt

 let defaults = UserDefaults.standard
        let myarray = defaults.stringArray(forKey: "ScheduleArray") ?? [String]()
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: myarray[(indexPath?.row)!] )
                    UserDefaults.standard.synchronize()

                }else{
                    btnChk2.isSelected = true
                    UserDefaults.standard.set((indexPath?.row)! + index, forKey: myarray[(indexPath?.row)!])
                    UserDefaults.standard.synchronize()
                }
            }
            sender.isSelected = false
        }

更改复选框已单击

不要在 UserDefaults 中保存索引路径,保存您在 table 单元格中显示的任何值。并将其与 cellForRowAtIndex 中的数组匹配。像我一样

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
    let c = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! tabCell
    c.lblC.text = arry?[indexPath.row]
    /* for example
     arry = ["First","Second","Third","Fourth","Fifth","Sixth","Seventh","eight","Ninth","Tenth"]
    seleted = ["First","Fifth"]
    */
    print("indexpath--",indexPath.row)
    if selected != nil
    {
        if (selected?.contains((arry?[indexPath.row])!))!
        {
            c.btnCheck.setBackgroundImage(#imageLiteral(resourceName: "check.png"), for: .normal)
        }
        else
        {
            c.btnCheck.setBackgroundImage(#imageLiteral(resourceName: "uncheck.png"), for: .normal)
        }


    }
    c.btnCheck.tag = indexPath.row
    c.btnCheck.addTarget(self, action:#selector(btnCheckClick(btn:)) , for: .touchUpInside)
    return c
}

我无法运行你的代码... 这就是我制作演示的方式 检查一下,希望你能得到一个想法... https://files.fm/u/hj7jz9dj