2016-11-23 3 views
0

Ich arbeite an einem Projekt in Swift 3.0 und ich habe zwei UITableViews, wo ich Daten aus einem Core-Datenmodul Entität namens UserIncome abgerufen. Da diese Daten in zwei UItableViews in einem einzigen UIViewController (Filterung basierend auf einem String-Wert in der ViewWillAppear-Delegate-Methode) aufgefüllt werden, wird das Array nach dem Löschen einer Zeile in einer UITableView automatisch auch von den anderen Objekten der tableView aktualisiert. Aber sobald ich auf den Zurück-Knopf klicke und zum selben UIViewController zurückkomme, scheint alles in Ordnung zu sein. Meine Anforderung besteht darin, die UItableView zu aktualisieren, sobald eine Zeile gelöscht wurde, so wie das Kerndatenmodul. Der Code wie folgt. Was fehlt mir hier?UITableView wird nicht aktualisiert, sobald die Zeile gelöscht wird

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

Post Tableview-Code zu, wo Sie Inhalte in es schreiben ... –

+0

Es ist dort, Sir – danu

+0

Try viewDidAppear() nicht tableView.reloadData() innerhalb func Tableview zu nennen (_ Tableview: UITableView, begehen editingStyle: UITableViewCellEditingStyle, forRowAt indexPath : IndexPath) – Rob

Antwort

1

müssen Sie Aufgabe wie auf diese Weise

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

diese löschen versuchen, hoffe, es wird Ihnen helfen,

+0

Ich tat das auch, aber es scheint immer noch dasselbe zu sein. Wenn ich zum Beispiel eine Zeile in meiner ersten TableView lösche, werden die Werte der anderen TableView automatisch zu dieser TableView aufgefüllt. Würde mich sehr freuen, wenn Sie mir bei dieser kleinen Sache helfen könnten – danu

0

Ein Kerndatenobjekt wirklich keine Informationen enthalten. Es hat einen Zeiger auf einen Kontext und eine ID, also wenn Sie es nach Informationen fragen, geht es zum Laden, um zu fragen. Wenn das Objekt aus dem Kontext gelöscht wird, funktioniert das Verwaltungsobjekt, das Sie in Ihrem Array gespeichert haben, nicht mehr und wird abstürzen. Deshalb sollten Sie nie NSManagedObjects behalten. Entweder

a) Kopieren Sie die Werte aus den Kerndaten in ein anderes Objekt. Wenn Sie ein Objekt löschen möchten, müssen Sie es sowohl im Geschäft als auch in der Kopie, die Sie behalten, löschen. Wenn neue Objekte eingefügt werden oder sie aus einer anderen Quelle außerhalb von ViewController gelöscht werden, wird sie nicht aktualisiert (aber auch kein Absturz).

b) Verwenden Sie einen NSFetchedResultsController und aktualisieren Sie die Ergebnisse, wenn sich die Werte ändern. Dies gibt einem Delegierten, Ihnen zu sagen, wenn Änderungen passieren. Also alles, was Sie tun müssen, löschen Sie das Objekt aus dem Speicher und dann wird die abgerufeneResultsController Ihnen sagen, wann es zu entfernen.

Verwandte Themen