3

I am using fmdb to manage some data that is display on a regular UITableView. I am attempting to delete one cell using this code:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        db = [FMDatabase databaseWithPath:[Utility getDatabasePath]];


        [db open];

        [db beginTransaction];

        NSString * stringtoInsert = [NSString stringWithFormat: @"DELETE FROM TTLogObject WHERE id='%@'", [idArray objectAtIndex:indexPath.row]];

        BOOL success = [db executeUpdate:stringtoInsert];

        if (!success)
        {
            NSLog(@"insert failed!!");
        }

        NSLog(@"Error %d: %@", [db lastErrorCode], [db lastErrorMessage]);

        [db commit];

        [db close];

        [self getList];
    }
}

Here is the code for viewDidLoad and the getList function that I am using.

   - (void)viewDidLoad
{
    [super viewDidLoad];

     self.navigationController.navigationBar.tintColor = [UIColor blackColor];

    shipperCityArray = [[NSMutableArray alloc] init];
    pickupDateArray = [[NSMutableArray alloc] init];
    paidArray = [[NSMutableArray alloc] init];
    idArray = [[NSMutableArray alloc] init];

    //NSString *path  = [[NSBundle mainBundle] pathForResource:@"tt" ofType:@"db"];


    [self getList];

}

- (void)getList
{
    db = [FMDatabase databaseWithPath:[Utility getDatabasePath]];
    [shipperCityArray removeAllObjects];
    [pickupDateArray removeAllObjects];
    [paidArray removeAllObjects];
    [idArray removeAllObjects];

    [db open];

    FMResultSet *fResult= [db executeQuery:@"SELECT * FROM TTLogObject"];


    while([fResult next])
    {
        [shipperCityArray addObject:[fResult stringForColumn:@"shipperCity"]];
        [pickupDateArray addObject:[fResult stringForColumn:@"pickupDate"]];
        [paidArray addObject:[NSNumber numberWithBool:[fResult boolForColumn:@"paid"]]];
        [idArray addObject:[NSNumber numberWithInteger:[fResult intForColumn:@"id"]]];
        NSLog(@"%@", [NSNumber numberWithInteger:[fResult intForColumn:@"id"]]);
    }


    [db close];

    [self.tableView reloadData];
}

The issue is that the data gets deleted just fine from the database. However, after delete is pressed, the table view does not display any cells anymore. When I restart the app, the proper data gets loaded again, with the cell that was deleted actually gone. I suspect it has something to do with numberOfRowsInSection.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSLog(@"%i", [shipperCityArray count]);
    return [shipperCityArray count];
}

When the app is launched, it prints the proper amount of cells, but when delete is hit, it does not print anything, and seems to not be called.

I have attempted to use [self.tableView beginUpdates] and [self.tableView endUpdates] but those seem to error out stating something about the wrong number of items resulting after the delete. I am not sure how to solve this. If I must use beginUpdates and endUpdates, can someone explain to me how this should be done properly, and what is actually going on?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Paulius Dragunas
  • 1,702
  • 3
  • 19
  • 29

1 Answers1

4

Instead of calling reloadData, you need to explicitly tell your tableView you are deleting a cell. Replace

[self.tableView reloadData];

with

[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];

You should call this in your commitEditingStyle method.

Erik Godard
  • 5,930
  • 6
  • 30
  • 33
  • I am attempting to use that, what do i pass to deleteRowsAtIndexPaths? Right now, if I just leave the line of code as is I get this error: -[NSIndexPath count]: unrecognized selector sent to instance 0x7566e50 2013-08-19 22:57:28.808 Trucking Tracker[13861:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSIndexPath count]: unrecognized selector sent to instance 0x7566e50' – Paulius Dragunas Aug 20 '13 at 03:58
  • It expects an array of index paths, not one, so you have to give it a one element array. I just updated it, sorry about that. – Erik Godard Aug 20 '13 at 04:01
  • Ah, I have tried that. And if I do it as shown, it gives me this: *** 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 (2) must be equal to the number of rows contained in that section before the update (2), 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).' – Paulius Dragunas Aug 20 '13 at 04:03
  • You need to call it after you call the getList method, so that the count method returns the correct number of elements. – Erik Godard Aug 20 '13 at 04:04
  • Hmm, I am just not having luck with this, now it's giving me this: *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-2380.17/UITableView.m:862 2013-08-19 23:06:22.926 Trucking Tracker[14743:c07] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete row 3 from section 0 which only contains 3 rows before the update' – Paulius Dragunas Aug 20 '13 at 04:06
  • Got it, reloadData was still being called in getList, that just needed to be deleted. Thank you – Paulius Dragunas Aug 20 '13 at 04:15