0

Hauptziel: In der ersten Ansicht Controller Ich werde auf eine Schaltfläche in einer Zelle tippen -> Schaltfläche ruft entity.removeFrom "" (_ value: "") Methode -> sollte automatisch die entsprechende Zelle aus einer Tabellenansicht in einem zweiten View-Controller entfernen.Swift to-Many Beziehung .removeFromMethod() aktualisiert nicht NSFetchedResultsController

Was geschieht: "" ... entity.removeFrom " "(_ Wert:"") Methode -> Objekt entfernt ist, auf Null gesetzt, jedoch NSFetchedResultsController nicht die entsprechenden Zeilen zu löschen. Verlassen der Tabellenansicht gefüllt mit leeren Zellen (aus den verbleibenden Nil-Objekten)

Frage: Wie Sie viele Objekte in der To-Viele-Beziehung entfernen und NSFetchedResultsController entsprechend aktualisieren.

Über die App Mit swift 3 Ich erstelle eine grundlegende To-Do-Liste App mit einem Tab-Leiste-Controller.

Erste tab = A tableView von ToDoItem

Zweite tab = Beendet toDoItems in einem NSFetchedResultsController

Core Data Entities: FinishedCollection, ToDoItem

FinishedCollection hat eine Eins-zu-viele-Beziehung mit todoItems (Ziel ist ToDoItem)

Reihenfolge der Bedienung: Set

Erster Tab

1) ToDoItem Attribut isFinished

2) FinishedCollection.addToToDoItems(toDoItem) oder FinishedCollection.removeFromToDoItems(toDoItem)

3) automatisch aktualisiert Zweiten Tab NSFetchedResultsController

PROBLEM: Wenn ich removeFromToDoItems(toDoItem) t Die Eigenschaft im NSFetchedResults-Controller wird auf Null gesetzt, anstatt das Objekt vollständig zu entfernen (ich möchte das Objekt nicht unbedingt vollständig entfernen). Dies führt zu leeren Zellen und einer Million Fragillion nil-Objekten. Wie gehe ich dazu über, die vielen Nil-Objekte in der Eins-zu-viele-Beziehung zu entfernen und nur in der NSFetchedResults-Controller-Tableview-Registerkarte zu beenden.

-

Attempt nil Objekte zu filtern, wenn numberOfRowsInSection tableview Verfahren setzen.Scheint nicht alles in diesem Umstand

let notNilObjects = sectionInfo.objects.flatMap { 0 } 

TableViewDataSource Methoden

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    let sections = fetchedResultsController?.sections 
    let sectionInfo = sections?[section] 

    return sectionInfo?.numberOfObjects ?? 1 
    } 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "JournalCell", for: indexPath) 

    configure(cell, atIndexPath: indexPath) 

    return cell 
    } 

// NSFetchedResultsDelegate Methoden

fileprivate func configure(_ cell: UITableViewCell, atIndexPath indexPath: IndexPath) { 
    guard let selectedObject = fetchedResultsController?.object(at: indexPath) else { 
    fatalError("Unexpected Object in FetchedResultsController") 
    } 

    let toDoItems = selectedObject.dayTasks?.allObjects as! [ToDoItem] 
    let toDo = ToDoItems.last 

    print(toDo?.name) 
} 

func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { 
    tableView.beginUpdates() 
} 

func controller(_ controller    : NSFetchedResultsController<NSFetchRequestResult>, 
       didChange sectionInfo  : NSFetchedResultsSectionInfo, 
       atSectionIndex sectionIndex: Int, 
       for type     : NSFetchedResultsChangeType) { 
    switch type { 
    case .insert: 
    tableView.insertSections(NSIndexSet(index: sectionIndex) as IndexSet, with: .fade) 
    case .delete: 
    tableView.deleteSections(NSIndexSet(index: sectionIndex) as IndexSet, with: .fade) 
    case .move: 
    break 
    case .update: 
    tableView.reloadData() 
    } 
} 

func controller(_ controller  : NSFetchedResultsController<NSFetchRequestResult>, 
       didChange anObject: Any, 
       at indexPath  : IndexPath?, 
       for type   : NSFetchedResultsChangeType, 
       newIndexPath  : IndexPath?) { 
    switch type { 
    case .insert: 
    tableView.insertRows(at: [newIndexPath!], with: .fade) 
    case .delete: 
    tableView.deleteRows(at: [indexPath!], with: .fade) 
    case .update: 
    configure(tableView.cellForRow(at: indexPath!)!, atIndexPath: indexPath!) 
    case .move: 
    tableView.moveRow(at: indexPath!, to: newIndexPath!) 
    } 
} 

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { 
    tableView.endUpdates() 
} 


func initializeFetchedResultsController() { 
    let request: NSFetchRequest = ToDoItem.fetchRequest() 
    request.sortDescriptors = [ NSSortDescriptor(key: "timestamp", ascending: true), 
           NSSortDescriptor(key: "isAccomplished", ascending: true) ] 

fetchedResultsController = NSFetchedResultsController(fetchRequest  : request, 
                 managedObjectContext: CoreDataHelper.context, 
                 sectionNameKeyPath : nil, 
                 cacheName   : nil) 
    fetchedResultsController?.delegate = self 

    do { 
    try fetchedResultsController?.performFetch() 
    } 
    catch { 
    print("Couldn't fetch results controller") 
    } 
} 
+1

zuweisen, was auf dem das Prädikat tut FetchedResultsController sieht aus? Warum haben Sie auch eine 'FinishedCollection' anstatt sich nur auf die 'isFinished' Eigenschaft zu verlassen? –

+0

Ich glaube, ich hatte das Problem viel komplizierter gemacht, als es hätte sein sollen. Das Holen der ursprünglichen Entität und das Verwenden der Eigenschaft isFinished zum Filtern funktioniert problemlos. Allerdings scheint es, alle Elemente im Core Data Kontext in den fetchedResultsController werden und können nicht die isfinished herauszufiltern = false ein Prädikat verwendet wird. Neues Problem zu lösen, irgendwelche Vorschläge? – lifewithelliott

+0

teilen Sie Ihren Abrufcode. –

Antwort

1

In Ihrem initializeFetchedResultsController Methode zu tun hinzufügen

request.predicate = NSPredicate(format: "isFinished = 1") 
0

Um eine NSSet zu filtern erworben von einem fetchedResultsController muss man eine NSPredicate verwenden und an die request.predicate Eigenschaft eines NSFetchRequest

Beispiel

let request = Entity.fetchRequest() 

request.predicate = NSPredicate(format: "isAccomplished == YES") 
Verwandte Themen