无法保存 UITableViewCell 的 on/off 状态?

unable to save on/off state of a UITableViewCell?

在名为 'Item'

的实体中有两个属性 'time' 和 'isOn' (string, bool)

in viewcontroller class 我可以为 'isOn' 属性(在 savePressed 函数中)提供默认条件,这使得 switchbtn.isOn = true 并将其保存在数据中该特定 'time'

的模型

viewcontroller class :-

class ViewController: UIViewController {

    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

    @IBOutlet weak var timePickerView: UIDatePicker!

    @IBOutlet weak var timeLbl: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        timePickerView.setValue(UIColor.white, forKeyPath: "textColor")
        dateFormat()

        // Do any additional setup after loading the view.
    }

    @IBAction func savePressed(_ sender: UIBarButtonItem) {
        let entity = Item(context: context)
        entity.time = timeLbl.text
        entity.isOn = true
        saveData()
        self.dismiss(animated: true, completion: nil)
    }

    @IBAction func cancelPressed(_ sender: UIBarButtonItem) {

        self.dismiss(animated: true, completion: nil)

    }

    @IBAction func valueChanged(sender:UIDatePicker, forEvent event: UIEvent){
        dateFormat()
    }

    func saveData() {
        (UIApplication.shared.delegate as! AppDelegate).saveContext()
    }

    func dateFormat() {
        let formatter = DateFormatter()
        formatter.dateFormat = "HH:mm"
        formatter.timeStyle = .short
        timeLbl.text = formatter.string(from: timePickerView.date)
    }

}

viewcontroller

在这个 class 中,我能够获取并显示核心数据,但不知道如何保存单元格切换按钮的状态并更新数据模型,因为没有使用 'didSelectRowAt'函数

表格视图class:-

class TableViewController: UITableViewController {

    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

    var items = [Item]()

    override func viewDidLoad() {
        super.viewDidLoad()
        print(arr)
    }

    override func viewWillAppear(_ animated: Bool) {
        getData()
        tableView.reloadData()
    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {

        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return items.count
    }


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath) as! TableViewCell

        cell.timeLbl.text = items[indexPath.row].time
        cell.switchBtn.isOn = items[indexPath.row].isOn

        return cell
    }

    func getData() {
        let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
        do {
             items = try context.fetch(Item.fetchRequest())
        }catch{
            print("failed to get the data")
        }

    }

}

tableview

在此我可以打印开关的当前状态,但无法从表视图 class

访问 'items[indexPath.row]'

单元格class:-

class TableViewCell: UITableViewCell {

    @IBOutlet weak var timeLbl: UILabel!

    @IBOutlet weak var switchBtn: UISwitch!

    var alarm = Bool()

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

    @IBAction func valChange(_ sender: UISwitch) {
        if sender.isOn{
            switchBtn.isOn = true
        }else {
            switchBtn.isOn = false
        }
    }
}

在 Swift 中,最有效的方法是回调闭包。

在单元格中添加一个 属性 callback,闭包传递 Bool 值而不传递 return 值。当switch的值改变时调用回调

class TableViewCell: UITableViewCell {

    @IBOutlet weak var timeLbl: UILabel!
    @IBOutlet weak var switchBtn: UISwitch!

    var alarm = Bool()

    var callback : ((Bool) -> Void)?

    @IBAction func valChange(_ sender: UISwitch) {
        callback?(sender.isOn)
    }
}

cellForRow控制器中添加回调,在闭包中更新模型。

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath) as! TableViewCell

    let item = items[indexPath.row]
    cell.timeLbl.text = item.time
    cell.switchBtn.isOn = item.isOn

    cell.callback = { newValue in
        self.items[indexPath.row].isOn = newValue
    }

    return cell
}

如果可以插入、删除或移动单元格,则还必须传递单元格以获取实际索引路径

class TableViewCell: UITableViewCell {

    @IBOutlet weak var timeLbl: UILabel!
    @IBOutlet weak var switchBtn: UISwitch!

    var alarm = Bool()

    var callback : ((UITableViewCell, Bool) -> Void)?

    @IBAction func valChange(_ sender: UISwitch) {
        callback?(self, sender.isOn)
    }
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath) as! TableViewCell

    let item = items[indexPath.row]
    cell.timeLbl.text = item.time
    cell.switchBtn.isOn = item.isOn

    cell.callback = { currentCell, newValue in
        let currentIndexPath = tableView.indexPath(for: currentCell)!
        self.items[currentIndexPath.row].isOn = newValue
    }

    return cell
}