2016-11-23 62 views
0

我在swift 3.0的项目中工作,我有两个UITableViews,我从一个名为UserIncome的核心数据模块实体设置数据。由于这些数据将填充到单个UIViewController中的两个UItableViews中(基于ViewWillAppear委托方法中的字符串值进行过滤),一旦在一个UITableView中删除了一行,其数组也会自动被其他tableView的对象更新。但是,一旦我点击后退按钮并回到相同的UIViewController似乎都很好。我的要求是更新UItableView,一旦行被删除,作为核心数据模块。代码如下。我在这里错过了什么?一旦行被删除,UITableView不会更新

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 

    var rowTbl : Int! 
    var rowTbl2 : Int! 



    override func viewDidLoad() { 
     super.viewDidLoad() 

} 
    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") 
     } 


    } 

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

     if tableView.tag == 1 { 
     let cell: RecuringIncomeTableViewCell = tableView.dequeueReusableCell(withIdentifier: "recurringIncomeCell") as! RecuringIncomeTableViewCell 

     let store = stores [indexPath.row] 

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


     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 


      return cell 

     } 
    } 




    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
     //performSegue(withIdentifier: "editStore", sender: nil) 
     if tableView.tag == 1 { 
      rowTbl = tableView.indexPathForSelectedRow?.row 
      print("current row in tbl 1 is : ",rowTbl) 

     }else { 

      rowTbl2 = tableView.indexPathForSelectedRow?.row 
      print("current row in tbl 2 is : ",rowTbl2) 
     } 

    } 
    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 { 
     print("delete delegate being activated") 
     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 tableView.tag == 1 { 
      if editingStyle == .delete { 
       let task = stores [indexPath.row] 
       context.delete(task) 
       (UIApplication.shared.delegate as! AppDelegate).saveContext() 


       do { 
        stores = try context.fetch(UserIncome.fetchRequest()) 
        print("Stores deleted from indexPath",stores) 
       }catch{ 
        print("fail") 
       } 


       recurringIncomeTableView.reloadData() 

      } 

      self.recurringIncomeTableView.reloadData() 

     } else if tableView.tag == 2 { 
      if editingStyle == .delete { 
       let task = other[indexPath.row] 
       print("task on otherTblView is : ",task) 
       context.delete(task) 
       (UIApplication.shared.delegate as! AppDelegate).saveContext() 
       otherIncomeTableView.reloadData() 

       do { 
        other = try context.fetch(UserIncome.fetchRequest()) 
        print("Stores deleted from indexPath",other) 
       }catch{ 
        print("fail") 
       } 

     } 


      self.otherIncomeTableView.reloadData() 
     } 
     tableView.reloadData() 


    } 


} 
+0

后实现代码如下代码太,你写在它的内容... –

+0

正是在那里爵士 – danu

+0

尝试调用viewDidAppear()不tableView.reloadData()FUNC的tableView内(_的tableView:UITableView的,提交editingStyle:UITableViewCellEditingStyle,forRowAt indexPath :IndexPath) – Rob

回答

1

您需要删除任务,像这样

let task = stores [indexPath.row] 
context.delete(task) 
stores.removeAtIndex(indexPath.row) // i think you forget this line 
(UIApplication.shared.delegate as! AppDelegate).saveContext() 

试试这个,希望它会帮助你

+0

我也这样做了,但看起来仍然是一样的。例如,如果我删除我的第一个tableView中的一行,其他tableView的值会自动填充到该tableView。如果你能帮助我解决这个小问题,我将非常感激 – danu

0

核心数据对象并没有真正包含的任何信息。它有一个指向上下文和ID的指针,所以当你询问信息时,它会去商店询问。如果该对象从上下文中删除,那么您存储在数组中的管理对象将不再起作用并且会崩溃。这就是为什么你永远不应该保留NSManagedObjects。或者

a)将核心数据中的值复制到不同的对象中。如果要删除某个对象,则必须将其从商店和您保留的副本中删除。如果插入新对象,或者从其他来源删除viewController,它将不会更新(但也不会崩溃)。

b)使用NSFetchedResultsController并在值更改时更新结果。这会让代表告诉你何时发生变化。因此,您只需从商店中删除该对象,然后fetchedResultsController会告诉您何时将其删除。