【问题标题】:Deleting the wrong row in a tableView删除 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)
        }
    }
}

【问题讨论】:

    标签: ios swift uitableview core-data


    【解决方案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 的评论很有帮助。无论如何,感谢您的快速反应。我将看看“闭包”,并尝试弄清楚这意味着什么:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-02
    • 1970-01-01
    • 1970-01-01
    • 2013-12-20
    • 2019-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多