删除tableView中的错误行

时间:2018-03-11 00:49:25

标签: ios swift uitableview core-data

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

2 个答案:

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