删除 tableView 中的错误行
Posted
技术标签:
【中文标题】删除 tableView 中的错误行【英文标题】:Deleting the wrong row in a tableView 【发布时间】:2018-03-11 00:49:24 【问题描述】:我是 Swift 的初学者,并尝试构建一个应用程序,其中一个数组通过 Core Data 将项目保存在 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)
【问题讨论】:
【参考方案1】:您的问题是您将错误的对象传递给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)
【讨论】:
哇!感谢您的快速帮助。现在它起作用了。现在我也可以删除最后一项了 :) 谢谢!【参考方案2】:这是因为您首先从数组中删除元素,然后删除单元格,最后保存数组。我建议首先删除元素,然后保存数组,最后从 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)
【讨论】:
Maddy 的评论很有帮助。无论如何,感谢您的快速反应。我将看看“闭包”,并尝试弄清楚这意味着什么:)以上是关于删除 tableView 中的错误行的主要内容,如果未能解决你的问题,请参考以下文章
使用 SearchBar 时,复选标记与 TableView 中的错误行相关联
Swift:tableView 行的高度,其 tableView 单元格具有动态行数的嵌套 tableView