无法保存UITableViewCell的打开/关闭状态? [英] unable to save on/off state of a UITableViewCell?

查看:60
本文介绍了无法保存UITableViewCell的打开/关闭状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

在viewcontroller类中,我可以给默认值条件为'isOn'属性(在savePressed函数中),该属性使switchbtn.isOn = true并将其保存在该特定时间的数据模型中



viewcontroller类:-

  class ViewController:UIViewController {

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

@IBOutlet弱var timePickerView:UIDatePicker!

@IBOutlet弱var timeLbl:UILabel!

覆盖功能funD viewDidLoad(){
super.viewDidLoad()
timePickerView.setValue(UIColor.white,forKeyPath: textColor)
dateFormat()

//加载视图后执行任何其他设置。
}

@IBAction func savePressed(_发件人:UIBarButtonItem){
let实体=项目(上下文:上下文)
实体。时间= timeLbl.text
Entity.isOn = true
saveData()
self.dismiss(动画:true,完成:nil)
}

@IBAction func cancelPressed(_ sender :UIBarButtonItem){

self.dismiss(动画:true,完成:无)

}

@IBAction func valueChanged(sender:UIDatePicker, forEvent事件: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(来自:timePickerView.date)
}

}

<一小时f = https://i.stack.imgur.com/mItM4.png rel = nofollow noreferrer> viewcontroller



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



tableview类:-

 类TableViewController:UITableViewController {

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

var项目= [Item]()

覆盖func viewDidLoad(){
super.viewDidLoad()
打印(arr)
}

覆盖func viewWillAppear(_动画:Bool){
getData()
tableView.reloadData()
}

//标记:-表格视图数据源

覆盖了func numberOfSections(在tableView中:UITableView)-> Int {

return 1
}

覆盖func tableView(_ tableView:UITableView,numberOfRowsInSection部分:Int)-> Int {

return items.count
}


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

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

返回单元格
}

func getData(){
let context =(UIApplication.shared.delegate as!AppDelegate).persistentContainer.viewContext
do {
items = try context.fetch(Item.fetchRequest())
} catch {
print(未能获取数据)
}

}

}

表视图



在此操作中,我可以打印交换机的当前状态,但无法访问tableview类中的 items [indexPath.row]



单元格类:-

  Class TableViewCell:UITableViewCell {

@IBOutlet弱var timeLbl:UILabel!

@IBOutlet弱var switchBtn:UISwitch!

var警报= Bool()

覆盖功能awakeFromNib(){
super.awakeFromNib()
//初始化代码
}

覆盖函数setSelected(_选择:Bool,动画:Bool){
super.setSelected(选择,动画:动画)

//配置视图所选状态
}

@IBAction函数valChange(_ sender:UISwitch){
if sender.isOn {
switchBtn.isOn = true
}否则{
switchBtn.isOn = false
}
}
}


解决方案

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



在单元格中添加属性回调,闭包传递 Bool 值,没有返回值。当开关的值更改时,调用回调。

  class TableViewCell:UITableViewCell {

@IBOutlet弱var timeLbl:UILabel!
@IBOutlet弱变量switchBtn:UISwitch!

var警报= Bool()

var回调:(((Bool)-> Void)?

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

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

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

让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弱var timeLbl: UILabel!
@IBOutlet弱var switchBtn:UISwitch!

var警报= Bool()

var回调:(((UITableViewCell,Bool)-> Void)?

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

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

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

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

返回单元格
}


there are two attributes 'time' and 'isOn' (string, bool) in the entity named 'Item'

in viewcontroller class I am able to give default condition to 'isOn' attribute (in savePressed function) which makes switchbtn.isOn = true and saves it in the data model for that particular '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

in this class I am able to fetch and show the core data but don't know how to save the state of the cell switch button and update the data model as there is no use of 'didSelectRowAt' function

tableview 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

in this I am able to print the current state of the switch but cannot access the 'items[indexPath.row]' from the tableview class

cell 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
        }
    }
}

解决方案

In Swift the most efficient way is a callback closure.

In the cell add a property callback with a closure passing a Bool value and no return value. Call the callback when the value of the switch changed.

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)
    }
}

In cellForRow in the controller add the callback, in the closure update the model.

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
}


If cells can be inserted, deleted or moved you have to pass also the cell to get the actual index path

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)
    }
}

and

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
}

这篇关于无法保存UITableViewCell的打开/关闭状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆