一旦按下滑动删除按钮,删除功能(提交编辑样式功能)会导致应用程序崩溃

Posted

技术标签:

【中文标题】一旦按下滑动删除按钮,删除功能(提交编辑样式功能)会导致应用程序崩溃【英文标题】:Delete function (commit editingStyle function) cause crashing the application once the swipe delete button is pressed 【发布时间】:2016-11-09 05:37:15 【问题描述】:

我正在 swift 3.0 中开展一个项目,我正在将数据从 核心数据 提取到两个 tableView 上,即:'recurringIncomeTableView' 和 'otherIncomeTableView强>'。但是,当“commit editingStyle”功能被激活时(一旦我滑动该行),我可以删除“recurringIncomeTableView”中的特定行。但是当我在“otherIncomeTableView”中滑动一行并按下 delete 时,在“let task = stores [indexPath.row]”行中导致问题并且应用程序崩溃了。代码如下。

import UIKit
import CoreData

class MyIncomesViewController: UIViewController, UITableViewDelegate, UITableViewDataSource 
    @IBOutlet weak var recurringIncomeTableView: UITableView!
    @IBOutlet weak var otherIncomeTableView: UITableView!
    //var myIncomeType : String?

    var stores = [UserIncome] ()
    var other = [UserIncome] ()
    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext



    override func viewDidLoad() 
        self.recurringIncomeTableView.reloadData()
        self.otherIncomeTableView.reloadData()


   override func viewDidAppear(_ animated: Bool) 

        stores.removeAll()
        other.removeAll()

        let request = NSFetchRequest <NSFetchRequestResult> (entityName: "UserIncome")
        request.returnsObjectsAsFaults = false



        do 

            let results = try context.fetch(request) as! [UserIncome]

            print("Results from the fetch request are : ", request)

            // check data existance
            if results.count>0 
                print("results are :", results.count)

                for resultGot in results 

                    //lets check if the data is available and whether the loop is working by printing out the "name"
                    if let incName = resultGot.incomeName 
                        print("expence name is :", incName)

                        //set the value to the global variable as to filter the arrays 
                        let myIncomeType = resultGot.incomeType

                        if myIncomeType == "Recurring Income"

                          stores += [resultGot]
                          print("my recurring income array is : \(stores)")
                        else if myIncomeType == "Other Income"

                          other += [resultGot]
                          print("my other income array is : \(other)")
                        
                    
                
                self.recurringIncomeTableView.reloadData()
                self.otherIncomeTableView.reloadData()

            

        catch


            print("No Data to load")
        


    
   @IBAction func addIncome(sender: UIButton) 
        print("Add Income Button Clicked")
        performSegue(withIdentifier: "ShowAddIncomeVC", sender: nil)
        // Do whatever you need when the button is pressed
    


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        if tableView == self.recurringIncomeTableView 
            print("recurringIncomeTableView count is ", stores.count)
         return stores.count
        else 
            print("otherIncomeTableView count is ", other.count)
         return other.count
        
    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

        if tableView == self.recurringIncomeTableView 
        let cell: RecuringIncomeTableViewCell = tableView.dequeueReusableCell(withIdentifier: "recurringIncomeCell") as! RecuringIncomeTableViewCell

        let store = stores [indexPath.row]

        cell.incomeNameLabel.text = store.incomeName
        cell.amountLabel.text = store.amount



        //cell.textLabel?.text = myExpensesArray[indexPath.row]
        return cell

        else 
            let cell: OtherIncomeTableViewCell = tableView.dequeueReusableCell(withIdentifier: "otherIncomeCell") as! OtherIncomeTableViewCell

            let otherIncomes = other [indexPath.row]

            cell.incomeNameLabel.text = otherIncomes.incomeName
            cell.amountLabel.text = otherIncomes.amount


            //cell.textLabel?.text = myExpensesArray[indexPath.row]
            return cell

        
    




    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
        //performSegue(withIdentifier: "editStore", sender: nil)

    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
        if segue.identifier == "editRecurringIncome"

            let v = segue.destination as! AddIncomeViewController
            let indexPath = self.recurringIncomeTableView.indexPathForSelectedRow
            let row = indexPath?.row
            v.store = stores[row!]

        else if segue.identifier == "editOtherIncome" 
            let t = segue.destination as! AddIncomeViewController
            let indexPath = self.otherIncomeTableView.indexPathForSelectedRow
            let row = indexPath?.row
            t.store = other [row!]


        
    

//    

    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool 
        return true
    

    //For remove row from tableview & object from array.
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) 
        let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

        if editingStyle == .delete 
            **let task = stores [indexPath.row]**
            context.delete(task)
            (UIApplication.shared.delegate as! AppDelegate).saveContext()

            do 
                stores = try context.fetch(UserIncome.fetchRequest())
            catch
                print("fail")
            
        
        tableView.reloadData()


    


【问题讨论】:

您需要在问题中包含完整的错误消息。 从另一个表中删除时,您不应该访问other 数组,而不是stores 数组吗? 您要从哪个表中删除您的行? self.recurringIncomeTableViewself.otherIncomeTableView ?也请在您的问题中提及您的崩溃。 先生,应用程序仅在从“self.otherIncomeTableView”中删除一行时才会崩溃 请尝试在此函数中指定tableView。如果 tableView == self.recurringIncomeTableView ..... 【参考方案1】:

根据您的 Core data 获取请求代码。

您必须将 core data 对象存储在您的存储数组中,而不是您可以直接从存储数组中删除该对象。

你需要像这样获取对象:

// Initialize Fetch Request
let fetchRequest = NSFetchRequest()

// Create Entity Description
let entityDescription = NSEntityDescription.entityForName("UserIncome", inManagedObjectContext: self.managedObjectContext)

// Configure Fetch Request
fetchRequest.entity = entityDescription

store = try self.managedObjectContext.executeFetchRequest(fetchRequest)

获得所有数据后,您必须根据您的要求过滤数组并将其显示在表格视图中,我只是举例说明如何在 tableview 中显示该数据。

在单元格中显示您的数据,如下所示:

var data: NSManagedObject = store[indexPath.row] as NSManagedObject
Cell.textLabel?.text = data.valueForKeyPath("Name") as? String 

根据您的代码删除您的数据:

let task = stores [indexPath.row]
context.delete(task)
(UIApplication.shared.delegate as! AppDelegate).saveContext()

它将帮助您了解core datatableview 的流程。

【讨论】:

这有一些缺失的部分。如果仅在 viewController 加载时获取数据,则应将其从上下文中删除并将其从数组中删除。 (你没有从数组中删除它) 那部分用户需要实施,因为我刚刚提到他在哪里做错了,这样他就可以从崩溃中走出来。所以这个@ELKA不需要额外的细节 先生你能把完整的代码。如您所说,上面的代码似乎缺少部分。 没有工作,兄弟非常感谢您的努力。我想我错过了什么

以上是关于一旦按下滑动删除按钮,删除功能(提交编辑样式功能)会导致应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

IOS滑动删除和多行编辑导致按钮名称设置为默认

Swiftui 移除滑动删除功能

在 SwiftUI 中的列表上实现删除功能

改变滑动删除按钮样式

在编辑模式下删除表格行上的删除按钮⛔️

如何在swift 5中实现滑动中的两个垂直按钮以删除