Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

webznz

macrumors member
Original poster
Mar 8, 2011
82
0
Hobbitin
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.

Code:
#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

Code:
[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

macrumors 68040
Sep 2, 2008
3,114
93
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

macrumors member
Original poster
Mar 8, 2011
82
0
Hobbitin
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

macrumors 68040
Sep 2, 2008
3,114
93
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

macrumors member
Original poster
Mar 8, 2011
82
0
Hobbitin
Cool, thanks for the tip.. will look into it now,once I figure it out ill post my solution...
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.