My code appears to run just fine but when I swipe to delete a line within my UITableView, the app crashes with the following:
Error
LittleToDoApp[70390:4116002] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
ViewController.m
#import "ViewController.h"
#import "ToDoItem.h"
#import "ToDoItemSvcCache.h"
@interface ViewController ()
@end
@implementation ViewController
@synthesize tableView;
ToDoItemSvcCache *ToDoItemSvc = nil;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
ToDoItemSvc = [[ToDoItemSvcCache alloc] init];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)deleteToDoItem:(id)sender {
NSLog(@"Deleting ToDoItem");
[self.view endEditing:YES];
}
- (IBAction)addToDoItem:(id)sender {
[self.view endEditing:YES];
NSLog(@"saveToDoItem: entering");
ToDoItem *todoitem = [[ToDoItem alloc] init];
todoitem.todoitem = _toDoItem.text;
[ToDoItemSvc createToDoItem:todoitem];
[self.tableView reloadData];
NSLog(@"saveToDoItem: todoitem saved");
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = @"toDoItemCell";
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:simpleTableIdentifier];
}
ToDoItem *toDoItem = [[ToDoItemSvc retrieveAllToDoItems]
objectAtIndex:indexPath.row];
cell.textLabel.text = [toDoItem description];
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return [[ToDoItemSvc retrieveAllToDoItems] count];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"viewToDoItem"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
SecondViewController *destViewController = segue.destinationViewController;
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
destViewController.toDoItemName = cell.textLabel.text;
}
}
#pragma hiding status bar
- (BOOL)prefersStatusBarHidden {
return YES;
}
// here we get back from both styles
- (IBAction)unwindFromDetailViewController:(UIStoryboardSegue *)segue
{
// UIViewController *detailViewController = [segue sourceViewController];
NSLog(@"%@", segue.identifier);
}
//Allows the delete button to show up when left swipping a list item
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return YES - we will be able to delete all rows
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
// Will add code to actually delete a row here. Adding NSLog so we know its triggering though
NSLog(@"Deleted row.");
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView reloadData];
}
@end
ToDoItemSvc.h
#import <Foundation/Foundation.h>
#import "ToDoItem.h"
@protocol ToDoItemSvc <NSObject>
- (ToDoItem *) createToDoItem: (ToDoItem *) todoitem;
- (NSMutableArray *) retrieveAllToDoItems;
- (ToDoItem *) updateToDoItem: (ToDoItem *) todoitem;
- (ToDoItem *) deleteToDoItem: (ToDoItem *) todoitem;
@end
Full source
https://github.com/martylavender/LittleToDoApp/tree/Storyboards
Edit
Following up after the comment/s made by Fennelouski, should I have something along these lines?
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.toDoItem removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
[self.tableView reloadData];
}
}
Edit 2
This is what I am getting:
https://www.evernote.com/l/AJiah58lVhdGXIYO1F5yv6fJXc7k3WjRLNYB/image.png