How to delete row in table view core Data. Swift 3

后端 未结 1 1383
Happy的楠姐
Happy的楠姐 2020-12-18 17:31

I been researching how to delete a row from a table view which the data is in Core Data. I can\'t find anything online that would help me with my code. Im really new with Co

1条回答
  •  悲哀的现实
    2020-12-18 17:57

    You should always use "NSFetchedResultsController" whenever tableview deals with the Core Data, because "NSFetchedResultsController" is built keeping tableView in mind.

    It provides features which are useful for dealing with tableView

    1. Along with UITableViewDelegate & UITableviewdatasource protocols, adopt/conform to "NSFetchedResultsControllerDelegate" protocol.
    2. Then implement its 3 methods to delete the record from core data. And DON'T RELOAD the tableview. NSFetchedResultsController will take care of it.

    for eg. let's load the data from core data (Entity name = Movie)

    var fetchedResultsController: NSFetchedResultsController
    
    override func viewDidLoad()
    {
        super.viewDidLoad()
        loadData()
    }
    
    func loadData() 
    {
            fetchedResultController = getMovies(managedObjectContext: self.coreData.persistentContainer.viewContext)
            fetchedResultController.delegate = self
    }
    
    
    func getMovies(managedObjectContext: NSManagedObjectContext) -> NSFetchedResultsController 
    {
            let fetchedResultController: NSFetchedResultsController
    
            let request: NSFetchRequest = Movie.fetchRequest()
            let formatSort = NSSortDescriptor(key: "format", ascending: false)
            let nameSort = NSSortDescriptor(key: "title", ascending: true)
            request.sortDescriptors = [formatSort, nameSort]
    
            fetchedResultController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: managedObjectContext, sectionNameKeyPath: "format", cacheName: "MyMovieLibrary")
    
            do
            {
                try fetchedResultController.performFetch()
            }
            catch
            {
                fatalError("Error in fetching records")
            }
    
            return fetchedResultController
    }
    

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int
    {
        if let sections = fetchedResultController.sections
        {
            return sections.count
        }
        return 0
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        if let sections = fetchedResultController.sections
        {
            let currentSection = sections[section]
            return currentSection.numberOfObjects
        }
        return 0
    }
    
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        let cell = tableView.dequeueReusableCell(withIdentifier: "movieCell", for: indexPath) as! MovieTableViewCell
    
        let movie = fetchedResultController.object(at: indexPath)
        cell.configureCell(movie: movie)
    
        return cell
    }
    

    Delete a record from core data

    // Override to support editing the table view.
    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
    {
        let managedObjectContext = coreData.persistentContainer.viewContext
    
        if editingStyle == .delete
        {
            movieToDelete = fetchedResultController.object(at: indexPath)
    
            let confirmDeleteAlertController = UIAlertController(title: "Remove Movie", message: "Are you sure you would like to delete \"\(movieToDelete!.title!)\" from your movie library?", preferredStyle: UIAlertControllerStyle.actionSheet)
    
            let deleteAction = UIAlertAction(title: "Delete", style: UIAlertActionStyle.default, handler: { [weak self] (action: UIAlertAction) -> Void in
                managedObjectContext.delete((self?.movieToDelete!)!)
                self?.coreData.saveContext()
                self?.movieToDelete = nil
            })
    
            let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: { [weak self] (action: UIAlertAction) -> Void in
                self?.movieToDelete = nil
            })
    
            confirmDeleteAlertController.addAction(deleteAction)
            confirmDeleteAlertController.addAction(cancelAction)
    
            present(confirmDeleteAlertController, animated: true, completion: nil)
    
        }
    }
    
    func controllerWillChangeContent(_ controller: NSFetchedResultsController)
        {
            tableView.beginUpdates()
        }
    
    func controller(_ controller: NSFetchedResultsController, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?)
    {
        switch type
        {
        case NSFetchedResultsChangeType.delete:
            print("NSFetchedResultsChangeType.Delete detected")
            if let deleteIndexPath = indexPath
            {
                tableView.deleteRows(at: [deleteIndexPath], with: UITableViewRowAnimation.fade)
            }
        case NSFetchedResultsChangeType.insert:
            print("NSFetchedResultsChangeType.Insert detected")
        case NSFetchedResultsChangeType.move:
            print("NSFetchedResultsChangeType.Move detected")
        case NSFetchedResultsChangeType.update:
            print("NSFetchedResultsChangeType.Update detected")
            tableView.reloadRows(at: [indexPath!], with: UITableViewRowAnimation.fade)
        }
    }
    
    func controllerDidChangeContent(_ controller: NSFetchedResultsController)
    {
        tableView.endUpdates()
    }
    

    0 讨论(0)
提交回复
热议问题