Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
VeriS Code
1,124 PointscommitEditingStyle not being called
I'm trying to create a simple todo list app using core data. I've got the saving part right but when I try to use canEditRowAtIndexPath and commitEditingStyle all i can do is swipe left but no delete button.
Here's my code:
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle != .Delete{
return
}
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
managedContext.deleteObject(people[indexPath.row])
people.removeAtIndex(indexPath.row)
tableView.beginUpdates()
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
tableView.reloadData()
tableView.endUpdates()
}
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) - Bool { return true }
3 Answers
Nathan Tallack
22,164 PointsOk, here is how I am doing it in my core data app. And it works just fine.
override func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.Delete
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
let entry = fetchedResultsController.objectAtIndexPath(indexPath)
coreDataStack.managedObjectContext.deleteObject(entry as! NSManagedObject)
coreDataStack.saveContext()
}
func controllerWillChangeContent(controller: NSFetchedResultsController) {
tableView.beginUpdates()
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch type {
case NSFetchedResultsChangeType.Insert:
tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: UITableViewRowAnimation.Automatic)
case NSFetchedResultsChangeType.Delete:
tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Automatic)
case NSFetchedResultsChangeType.Update:
tableView.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Automatic)
default:
break
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
tableView.endUpdates()
}
Now I am using core data so the work I am doing to update my managed objects is a little different to the work you are doing. But the key difference here is that I am overriding the builtin methods for the UITableViewController class that I am subclassing. Maybe that is what you are doing wrong. Maybe you cant call this stuff directly like you are because you are just being overwritten by those existing methods inside the superclass.
So try implementing your actions as separate functions, overriding those in the UITableViewController class, and you may get the results you desire. :)
Nathan Tallack
22,164 PointsIt could be because your table is not marked as editable. You can do it programatically or via the attributes editor.
Search the apple developer docs for "marking a table as editable". :)
VeriS Code
1,124 PointsWhere can i find the editable checkbox in the attributes inspector?
Nathan Tallack
22,164 PointsApologies. I miss-rememebered that attribute. It is for enabling indenting when editing, not to allow editing.
After reading your code again I think I may have a suggestion.
Apple's guide on this method (which you can find here on their website) shows that you need to put all the code related to the delete action within the beginUpdates and endUpdates method calls. So it may be that you need to move your managed object methods inside there too.
Try it with your code looking like this.
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle != .Delete{
return
}
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
tableView.beginUpdates()
managedContext.deleteObject(people[indexPath.row])
people.removeAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
tableView.endUpdates()
tableView.reloadData()
}
VeriS Code
1,124 PointsUnfortunately that's not working, I think it may be a bug, but I'll still put your answer as best answer. I'll report this to Apple. Thanks for your help anyway :)
Nathan Tallack
22,164 PointsDo be sure to come back and update this post when you do find an answer so that we know how you fixed it. :)
Steven Deutsch
21,046 PointsHey VeriS,
Try moving the code inside the if block and moving putting the code related to the deletion between tableView.beginUpdates() and tableView.endUpdates().
Change if editingStyle != .Delete to ==
Make sure your function says override before it
Remove the return statement
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
tableView.beginUpdates()
managedContext.deleteObject(people[indexPath.row])
people.removeAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
tableView.endUpdates()
tableView.reloadData()
}
}
VeriS Code
1,124 PointsIt won't allow me to override it, without the override it's still the same. But thanks anyway :)
VeriS Code
1,124 PointsVeriS Code
1,124 PointsThank you so much! This helped me a lot! :)
Nathan Tallack
22,164 PointsNathan Tallack
22,164 PointsGlad we got there in the end. But I learnt how to do it now so that is a good thing for both of us. :)