Swift 撤消功能,先前声明的变量始终为空
Swift undo feature, previously declared variable is always empty
我正在尝试在删除 UITableView
中的单元格时实现撤消功能。要删除的单元格数据被声明为变量。删除部分工作正常,但是当我尝试 'undo' 删除时,变量始终为空。
实施
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: UITableViewRowAction.Style.destructive, title: "Delete") { (action, indexPath) in
let selectedExercise = self.exercises[indexPath.row]
//selectedExercise is declared here to be used in both
//`deleteExercise` and `undoDeleteExercise`
self.undoManager?.registerUndo(withTarget: self, handler: { (selfTarget) in
self.undoDeleteExercise(indexPath: indexPath, selectedExercise: selectedExercise)
})
self.deleteExercise(indexPath: indexPath, selectedExercise: selectedExercise)
let message = MDCSnackbarMessage()
message.text = "Removing Exercise"
let action = MDCSnackbarMessageAction()
action.handler = {() in
self.undoManager?.undo()
}
action.title = "UNDO"
message.action = action
MDCSnackbarManager.show(message)
}
return [delete]
}
正在删除
这按预期工作。所选练习将从数据库、练习数组和 tableView
.
中删除
func deleteExercise(indexPath: IndexPath, selectedExercise: Exercise){
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let _ : NSError! = nil
do {
managedContext.delete(selectedExercise as NSManagedObject)
exercises.remove(at: indexPath.row)
self.execisesTableView.deleteRows(at: [indexPath], with: .automatic)
try managedContext.save()
} catch {
print("error : \(error)")
}
ifNoExercises()
}
撤消删除
这里的问题是 selectedExercise
始终是一个空对象,因此尽管该行已添加到数据库中并且 tableView
它不包含任何信息。
func undoDeleteExercise(indexPath: IndexPath, selectedExercise: Exercise){
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let _ : NSError! = nil
do {
managedContext.insert(selectedExercise as NSManagedObject)
exercises.insert(selectedExercise, at: indexPath.row)
execisesTableView.insertRows(at: [indexPath], with: .automatic)
try managedContext.save()
} catch {
print("error : \(error)")
}
ifNoExercises()
}
对于遇到同样问题的任何人,这就是我解决的方法(这取代了 editActionsForRowAt
):
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let contextItem = UIContextualAction(style: .destructive, title: "Delete") { (contextualAction, view, boolValue) in
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let exerciseEntity = NSEntityDescription.entity(forEntityName: MyVariables.exerciseEntity, in: managedContext)!
let copiedExercise = NSManagedObject(entity: exerciseEntity, insertInto: managedContext)
let selectedExercise = self.exercises[indexPath.row]
copiedExercise.setValue(selectedExercise.distance, forKeyPath: MyVariables.distance)
copiedExercise.setValue(selectedExercise.end_time, forKeyPath: MyVariables.endTime)
copiedExercise.setValue(selectedExercise.lat_lngs, forKeyPath: MyVariables.latLngs)
copiedExercise.setValue(selectedExercise.map_string, forKeyPath: MyVariables.mapString)
copiedExercise.setValue(selectedExercise.start_time, forKeyPath: MyVariables.startTime)
self.undoManager?.registerUndo(withTarget: self, handler: { (selfTarget) in
self.undoDeleteExercise(indexPath: indexPath, selectedExercise: copiedExercise as! Exercise)
})
self.deleteExercise(indexPath: indexPath, selectedExercise: selectedExercise)
let message = MDCSnackbarMessage()
message.text = "Removing Exercise"
let action = MDCSnackbarMessageAction()
action.handler = {() in
self.undoManager?.undo()
}
action.title = "UNDO"
message.action = action
MDCSnackbarManager.show(message)
}
let swipeActions = UISwipeActionsConfiguration(actions: [contextItem])
return swipeActions
}
我正在尝试在删除 UITableView
中的单元格时实现撤消功能。要删除的单元格数据被声明为变量。删除部分工作正常,但是当我尝试 'undo' 删除时,变量始终为空。
实施
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: UITableViewRowAction.Style.destructive, title: "Delete") { (action, indexPath) in
let selectedExercise = self.exercises[indexPath.row]
//selectedExercise is declared here to be used in both
//`deleteExercise` and `undoDeleteExercise`
self.undoManager?.registerUndo(withTarget: self, handler: { (selfTarget) in
self.undoDeleteExercise(indexPath: indexPath, selectedExercise: selectedExercise)
})
self.deleteExercise(indexPath: indexPath, selectedExercise: selectedExercise)
let message = MDCSnackbarMessage()
message.text = "Removing Exercise"
let action = MDCSnackbarMessageAction()
action.handler = {() in
self.undoManager?.undo()
}
action.title = "UNDO"
message.action = action
MDCSnackbarManager.show(message)
}
return [delete]
}
正在删除
这按预期工作。所选练习将从数据库、练习数组和 tableView
.
func deleteExercise(indexPath: IndexPath, selectedExercise: Exercise){
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let _ : NSError! = nil
do {
managedContext.delete(selectedExercise as NSManagedObject)
exercises.remove(at: indexPath.row)
self.execisesTableView.deleteRows(at: [indexPath], with: .automatic)
try managedContext.save()
} catch {
print("error : \(error)")
}
ifNoExercises()
}
撤消删除
这里的问题是 selectedExercise
始终是一个空对象,因此尽管该行已添加到数据库中并且 tableView
它不包含任何信息。
func undoDeleteExercise(indexPath: IndexPath, selectedExercise: Exercise){
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let _ : NSError! = nil
do {
managedContext.insert(selectedExercise as NSManagedObject)
exercises.insert(selectedExercise, at: indexPath.row)
execisesTableView.insertRows(at: [indexPath], with: .automatic)
try managedContext.save()
} catch {
print("error : \(error)")
}
ifNoExercises()
}
对于遇到同样问题的任何人,这就是我解决的方法(这取代了 editActionsForRowAt
):
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let contextItem = UIContextualAction(style: .destructive, title: "Delete") { (contextualAction, view, boolValue) in
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let exerciseEntity = NSEntityDescription.entity(forEntityName: MyVariables.exerciseEntity, in: managedContext)!
let copiedExercise = NSManagedObject(entity: exerciseEntity, insertInto: managedContext)
let selectedExercise = self.exercises[indexPath.row]
copiedExercise.setValue(selectedExercise.distance, forKeyPath: MyVariables.distance)
copiedExercise.setValue(selectedExercise.end_time, forKeyPath: MyVariables.endTime)
copiedExercise.setValue(selectedExercise.lat_lngs, forKeyPath: MyVariables.latLngs)
copiedExercise.setValue(selectedExercise.map_string, forKeyPath: MyVariables.mapString)
copiedExercise.setValue(selectedExercise.start_time, forKeyPath: MyVariables.startTime)
self.undoManager?.registerUndo(withTarget: self, handler: { (selfTarget) in
self.undoDeleteExercise(indexPath: indexPath, selectedExercise: copiedExercise as! Exercise)
})
self.deleteExercise(indexPath: indexPath, selectedExercise: selectedExercise)
let message = MDCSnackbarMessage()
message.text = "Removing Exercise"
let action = MDCSnackbarMessageAction()
action.handler = {() in
self.undoManager?.undo()
}
action.title = "UNDO"
message.action = action
MDCSnackbarManager.show(message)
}
let swipeActions = UISwipeActionsConfiguration(actions: [contextItem])
return swipeActions
}