CG6578
CG6578

Reputation: 7

Swift: Delete a table view row from a table without removing it from the database it is stored in

In my application the user can delete various table cells. If rows are deleted, the program stores their ids in an array called deletedFeeds which uses NSUserDefaults. The program displays information from a Core Data database that updates every so often. This is the code which gets the information from the data base. It checks to make sure that the object it is looking is not in the array of deleted feeds to make sure it has not been deleted.

var fetchResultController: NSFetchedResultsController = NSFetchedResultsController()

func getFetchedResultController() -> NSFetchedResultsController {
    fetchResultController = NSFetchedResultsController(fetchRequest: feedFetchRequest(), managedObjectContext: managedObjectContext!, sectionNameKeyPath: nil, cacheName: nil)
    return fetchResultController
}

func feedFetchRequest() -> NSFetchRequest {
    let fetchRequest = NSFetchRequest(entityName: "Feed")
    let sortDescriptor = NSSortDescriptor(key: "url", ascending: false)
    let predicateOne = NSPredicate(format: "category == %@", theUrl!)
    let predicateTwo = NSPredicate(format: "not (%@ contains[c] url)", deletedFeeds)
    let predicate = NSCompoundPredicate(type: NSCompoundPredicateType.AndPredicateType, subpredicates: [predicateOne, predicateTwo])
    fetchRequest.predicate = predicate
    fetchRequest.sortDescriptors = [sortDescriptor]
    return fetchRequest
}

The problem is the fact that I cannot manually update the fetch request when deleting a row so the array goes out of index when it tries to generate the cells after removing the row because it is still expecting as many rows as there were before the row was deleted. How can I fix this? This is the code to delete a row:

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete {
        let item = fetchResultController.objectAtIndexPath(indexPath) as! Feed
        deletedFeeds.append(item.url)
        fetchResultController.performFetch(nil)
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        tableView.reloadData()
    }
}

Upvotes: 0

Views: 432

Answers (1)

Mundi
Mundi

Reputation: 80265

As has been suggested, you are abusing NSUserDefaults. Don't.

The information of the deleted feeds belongs in your database. You can add an attribute that keeps track of that.

Now, when you delete a row, you simply set the deleted flag to true.

Also note that reloadData is a crude way to update the table view. For changes in the table view due to external changes in your data, you should use the beginUpdates and endUpdates APIs to animate any change. For UI initiated changes (user deletes row) it should not be necessary to call reloadData.

Upvotes: 1

Related Questions