无法保存 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
}
在名为 '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
}