Delete a TableView + CoreData row

0

I'm creating an application with tables and persistence with CoreData , but when I ask to delete a line it does not disappear completely from the screen, leaving the symbol ... disappearing only when I go to a second screen and I go back. p>

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {


    let managedObject : NSManagedObject = frc.objectAtIndexPath(indexPath) as! NSManagedObject
    moc.deleteObject(managedObject)



    do{
        try moc.save()
    }catch{
        print("Error, data not saved!")
    }

        self.tableView.reloadData()


}

    
asked by anonymous 06.06.2016 / 19:01

1 answer

2

I'd advise you to use NSFetchedResultController . This is perfect for handling line + coredata editing in a TableView.

I'll describe a basic step-by-step of what you should do to get started with NSFetchedResultController :

  • Make your class inherit from NSFetchedResultsControllerDelegate ;
  • Then create a variable as follows:

    lazy var fetchedResultsController: NSFetchedResultsController = {
        let fetchRequest = NSFetchRequest(entityName: "NomeDaSuaEntidade")
        fetchRequest.sortDescriptors = [NSSortDescriptor(key: "atributoParaOrdenar", ascending: true)]
        let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.sharedContext, sectionNameKeyPath: nil, cacheName: nil)
        return fetchedResultsController
    }()
    
  • In viewDidLoad add the following code snippet:

    ...
    do {
        try fetchedResultsController.performFetch()
    } catch {}
    
    fetchedResultsController.delegate = self
    ...
    
  • To populate the table in the cellForRowAtIndePath method retrieve the objects as follows:

    ...
    let objeto = fetchedResultsController.objectAtIndexPath(indexPath) as! NomeDoSeuObjeto
    ...
    
  • In the numberOfRowsInSection method, retrieve the number of items as follows:

    ...
    let sectionInfo = self.fetchedResultsController.sections![section]
    return sectionInfo.numberOfObjects
    ...
    
  • Now the great charm of the NSFetchedResultController that makes it so worthwhile to use this delegate method that takes care of insertions, removals, updates and table row moves:

    func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
        switch type {
        case .Insert:
            self.tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
        case .Delete:
            self.tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
        case .Update:
            let cell = tableView.cellForRowAtIndexPath(indexPath!) as! ArtistCell
            let artist = controller.objectAtIndexPath(indexPath!) as! NomeDoSeuObjeto
            //preenche celula com dados do objeto
        case .Move:
            self.tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
            self.tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
        }
    }
    
  • Finally, add the following methods to make everything work perfectly:

    func controllerWillChangeContent(controller: NSFetchedResultsController) {
        self.tableView.beginUpdates()
    }
    
    func controllerDidChangeContent(controller: NSFetchedResultsController) {
        self.tableView.endUpdates()
    }
    
  • Following the steps above you will be able to make the removal of a cell work in addition to being able to take advantage of other benefits that this delegate has to offer.

    I'll also pass the link to a very good tutorial showing how it is done to complement what I said above: link (I know the tutorial is in English, but I do not find any good in Portuguese)

        
    23.06.2016 / 14:55