我是Swift的初学者,并尝试构建一个应用程序,其中数组将项目保存在CoreView的tableView中。这样可行。但是,通过滑动删除右行是不可行的。
首先删除右行。但是当我回到应用程序时,它是删除/不再显示的初始选定行上方的行。
有人可以提出建议吗?
以下是代码:
import UIKit
import CoreData
var shoppingList: [NSManagedObject] = [ ]
class ShoppingList_1: UIViewController, UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return shoppingList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = shoppingList[indexPath.row]
let cell = Cell.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = item.value(forKeyPath: "itemName") as? String
cell.detailTextLabel?.text = "\(indexPath.row)"
return cell
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let itemTmp = shoppingList[sourceIndexPath.row]
shoppingList.remove(at: sourceIndexPath.row)
shoppingList.insert(itemTmp, at: destinationIndexPath.row)
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete
{
shoppingList.remove(at: indexPath.row)
Cell.deleteRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
//Cell.reloadData()
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {return}
let managedContext = appDelegate.persistentContainer.viewContext
managedContext.delete(shoppingList[indexPath.row])
do {
try managedContext.save()
} catch let err as NSError {
print("12345", err)
}
}
}
@IBOutlet weak var AddButton: UIButton!
@IBOutlet weak var AddItem: UITextField!
@IBOutlet weak var Cell: UITableView!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {return}
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Item")
do {
shoppingList = try managedContext.fetch(fetchRequest)
} catch let err as NSError {
print("Failed to fetch items", err)
}
}
}
答案 0 :(得分:0)
您的问题是您将错误的对象传递给managedContext.delete
,因为您在从数组中删除项目后按索引访问元素。实际上,如果您尝试删除最后一行,您的应用就会崩溃。
如果您从Core Data中成功删除了值,则还应该只更新本地数据模型和表。
您应该按如下方式更新commit editingStyle
方法:
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete
{
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {return}
let managedContext = appDelegate.persistentContainer.viewContext
managedContext.delete(shoppingList[indexPath.row])
do {
try managedContext.save()
shoppingList.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
} catch let err as NSError {
print("12345", err)
}
}
}
答案 1 :(得分:-1)
这是因为您首先从数组中删除元素,然后删除单元格,最后保存数组。我建议首先删除元素,然后保存数组,最后从tableView中删除单元格。为了确保您的应用程序始终遵循此顺序,请使用闭包创建一个delete()函数。所有数据库的删除都应该在实际的函数中完成,并且必须在闭包中删除tableViewCell,以便确保在正确完成其他所有操作后删除它。
这是功能:
func deleteRows(closure: () -> ()) {
shoppingList.remove(at: indexPath.row)
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {return}
let managedContext = appDelegate.persistentContainer.viewContext
managedContext.delete(shoppingList[indexPath.row])
do {
try managedContext.save()
} catch let err as NSError {
print("12345", err)
return
}
closure()
}
这是你叫它:
deleteRows {
tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
}