PDA

View Full Version : Not sure how to delete UITableViewCells that are grouped in sections




webznz
Apr 12, 2011, 06:07 PM
Hi, I have implemented a UITableView with grouped style. in that table view their are two sections one section i have stopped it from being edited but the other rows are fine, i have an edit button and swipe to delete for these however because of the way i have set up tableView:cellForRowAtIndexPath: with different sections and row I think its stopping my rows from being deletable.

here is the code, and error message when I try to delete a cell.. if you have any suggestions on what im doing wrong that would be helpful.


#pragma mark -
#pragma mark Table view data source

// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}

//This method adds headings to my sections
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSString *title = nil;
// Return a title or nil as appropriate for the section.
switch (section) {
case SEARCH_SECTION:
title = @"Search";
break;
case ADVANCED_SECTION:
title = @"Advanced Search";
break;
default:
break;
}
return title;;
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSInteger rows = 0;
/*
The number of rows depends on the section.
In the case of ADVANCE_SECTION, if editing, add a row in editing mode to present an "Add ????" cell.
*/
switch (section) {
case SEARCH_SECTION:
rows = 2;
break;
case ADVANCED_SECTION:
rows = 1;

break;
default:
break;
}
return rows;
}



// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

if (indexPath.section == 0) {
if (indexPath.row == 0) {
return cellCode;
}
if (indexPath.row == 1) {
return cellManufacture;
}
if (indexPath.row == 2) {
return cellModel;
}
}
return cellYear;
}


// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
if (indexPath.section == 0) {
if (indexPath.row == 0) {
return NO;
}
if (indexPath.row == 1) {
return NO;
}
}
return YES;
}


// Override to support editing the table view. tableView:commitEditingStyle:forRowAtIndexPath:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source.
[self resignFirstResponder];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}


/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/


/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/



log



[Session started at 2011-04-13 11:06:41 +1200.]
2011-04-13 11:06:48.950 instaCode1.2[1395:207] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1447.6.4/UITableView.m:976
2011-04-13 11:06:48.953 instaCode1.2[1395:207] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 1. 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).'
*** Call stack at first throw:
(
0 CoreFoundation 0x00db0be9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x00f055c2 objc_exception_throw + 47
2 CoreFoundation 0x00d69628 +[NSException raise:format:arguments:] + 136
3 Foundation 0x000b447b -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
4 UIKit 0x00336a0f -[UITableView(_UITableViewPrivate) _endCellAnimationsWithContext:] + 8424
5 UIKit 0x00325f43 -[UITableView deleteRowsAtIndexPaths:withRowAnimation:] + 56
6 instaCode1.2 0x00002756 -[RootViewController tableView:commitEditingStyle:forRowAtIndexPath:] + 117
7 UIKit 0x003232ea -[UITableView(UITableViewInternal) animateDeletionOfRowWithCell:] + 101
8 UIKit 0x002b9a6e -[UIApplication sendAction:to:from:forEvent:] + 119
9 UIKit 0x003481b5 -[UIControl sendAction:to:forEvent:] + 67
10 UIKit 0x0034a647 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
11 UIKit 0x003491f4 -[UIControl touchesEnded:withEvent:] + 458
12 UIKit 0x002de0d1 -[UIWindow _sendTouchesForEvent:] + 567
13 UIKit 0x002bf37a -[UIApplication sendEvent:] + 447
14 UIKit 0x002c4732 _UIApplicationHandleEvent + 7576
15 GraphicsServices 0x016e6a36 PurpleEventCallback + 1550
16 CoreFoundation 0x00d92064 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
17 CoreFoundation 0x00cf26f7 __CFRunLoopDoSource1 + 215
18 CoreFoundation 0x00cef983 __CFRunLoopRun + 979
19 CoreFoundation 0x00cef240 CFRunLoopRunSpecific + 208
20 CoreFoundation 0x00cef161 CFRunLoopRunInMode + 97
21 GraphicsServices 0x016e5268 GSEventRunModal + 217
22 GraphicsServices 0x016e532d GSEventRun + 115
23 UIKit 0x002c842e UIApplicationMain + 1160
24 instaCode1.2 0x0000207c main + 102
25 instaCode1.2 0x0000200d start + 53
)
terminate called after throwing an instance of 'NSException'



PhoneyDeveloper
Apr 12, 2011, 06:28 PM
Read the description of the assertion failure carefully:

reason: 'Invalid update: invalid number of rows in section 1. 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).'


When you call deleteRowsAtIndexPaths: the table does some sanity checking. It calls your methods for numberOfSections and numberOfRowsInSections and checks if the new number of sections and rows matches the old numbers plus your changes. In your case you hard code the number of sections and number of rows so after you tell the table that you've deleted a row your data model still has the same number of rows. That doesn't make any sense. 1 - 1 != 1;

webznz
Apr 12, 2011, 06:56 PM
yea, would the best solution for the tableView:numberOfRowsInSection: be to set up a global variable that catches a increment from each row in tableView:cellForRowAtIndexPath: ? or is there a more efficent way of doing this?

PhoneyDeveloper
Apr 12, 2011, 09:28 PM
The usual way to do this is to have a data model that represents the data in the table. So a section is usually represented by an array of dictionaries. When the user deletes a row the code removes that dictionary from the array. The code in rowsForSection returns the number of items in the array, not a hard-coded number.

webznz
Apr 13, 2011, 04:26 PM
Cool, thanks for the tip.. will look into it now,once I figure it out ill post my solution...