UITableView deleteRowsAtIndexPath crash when delete last record - iphone

I'm encountering the following error when I delete the last record from a UITableView.
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 (3) 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 (1 inserted,
1 deleted) and plus or minus the number of rows moved into or out of
that section (0 moved in, 0 moved out).'
My goal is to show "No Record found" if the table array is empty.
This is the code I'm using. When I delete the last record from table array the app crashes. How is it possible to reload the table and show "No Record Found" label?
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if ([idArray count]==0) {
return 3;
}
else
{
return [idArray count];
}
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"array count %d",[idArray count]);
if ([idArray count] == 0) {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.textAlignment = UITextAlignmentCenter;
tableView.userInteractionEnabled = NO;
self.navigationItem.leftBarButtonItem.enabled = NO;
NSUInteger row = [indexPath row];
switch (row) {
case 0:
cell.textLabel.text = #"";
break;
case 1:
cell.textLabel.text = #"";
break;
case 2:
cell.textLabel.text = #"No Records Found";
break;
default:
break;
}
return cell;
}
else
{ static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
tableView.userInteractionEnabled = YES;
self.navigationItem.leftBarButtonItem.enabled = YES;
// Set up the cell
identify *idItems = [idArray objectAtIndex:indexPath.row];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"dd MMM,yyyy"];
NSString *dateStr = [formatter stringFromDate:idItems.Date];
UIImageView *accDis = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Arrow.png"]];
cell.accessoryView = accDis;
self.idTableView.separatorColor = [UIColor colorWithRed:150.0/255.0 green:150.0/255.0 blue:150.0/255.0 alpha:1];
cell.textLabel.textColor = [UIColor blackColor];
cell.textLabel.font = [UIFont boldSystemFontOfSize:18];
cell.textLabel.adjustsFontSizeToFitWidth = YES;
cell.detailTextLabel.textColor = [UIColor colorWithRed:100.0/255.0 green:100.0/255.0 blue:100.0/255.0 alpha:1];
cell.detailTextLabel.font = [UIFont italicSystemFontOfSize:16];
cell.detailTextLabel.adjustsFontSizeToFitWidth = YES;
NSString *detailText = [NSString stringWithFormat:#"%# - %#",dateStr,idItems.GeoCode];
if (idItems.Image == NULL) {
cell.imageView.image = [UIImage imageNamed:#"icon58x58.png"];
}
else
{
//pass image to fix size 50 X 50
//UIImage *newImage = [self postProcessImage:idItems.Image];
cell.imageView.image = idItems.thumb;//newImage;
cell.imageView.contentMode=UIViewContentModeScaleAspectFill;
}
cell.textLabel.text = idItems.TypeName;
cell.detailTextLabel.text = detailText;
return cell;
}
}
- (void)tableView:(UITableView *)tv commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {
if(editingStyle == UITableViewCellEditingStyleDelete) {
if ([idArray count] >=1)
{
[idTableView beginUpdates];
//Get the object to delete from the array.
identifyObject = [appDelegate.idArray objectAtIndex:indexPath.row];
//Delete the object from the table.
[self.idTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[appDelegate removeID:identifyObject];
if ([idArray count] == 0) {
[self.idTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
[idTableView endUpdates];
}
}
}

The problem is that a tableview expects the operations performed on the view to match the data source. You have one record in the table, and you remove it. The tableview is expecting the datasource to now contain zero records, but because of your "no records found" logic, it actually returns a value of 3, hence the consistency error, and your crash.
The bug seems to be this part:
if ([idArray count] == 0) {
[self.idTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
I assume this was intended to insert the "no records found" row into the table when the last line is deleted, but since your "no records found" actually spans three rows, you need to insert three rows here instead, like this:
if ([idArray count] == 0) {
[self.idTableView insertRowsAtIndexPaths:[NSArray arrayWithObjects:
[NSIndexPath indexPathForRow:0 inSection:indexPath.section],
[NSIndexPath indexPathForRow:1 inSection:indexPath.section],
[NSIndexPath indexPathForRow:2 inSection:indexPath.section],
nil] withRowAnimation:UITableViewRowAnimationFade];
}
For you own sanity however, can I suggest a different approach? Rather than trying to keep your table and datasource in sync whilst juggling these fake three rows of data that are only there for display purposes, why not just insert a UILabel into your view hierarchy (either in front of or behind the tableview) that says "no records found" and show/hide it based on whether the table has any data? That way you can precisely control its position and appearance without having to screw around with your datasource logic.

General rules for dealing with deleting rows are:
Deal with your model
Deal with row's animation
So for example:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSInteger row = [indexPath row];
[yourModel removeObjectAtIndex:row]; // you need to update your model
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
Now, in my opinion the correct code could be the following (I've written some comments to guide you).
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//Get the object to delete from the array.
identifyObject = [appDelegate.idArray objectAtIndex:indexPath.row];
[appDelegate removeID:identifyObject]; // update model first
// now you can check model count and do what you want
if ([appDelegate.idArray count] == 0) // I think you mean appDelegate.idArray
{
// do what you want
// with [self.idTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else
{
[self.idTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
}
Hope it helps.

I was using same approach where I used a cell for "No rows" warning.
For me, this worked:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[favs removeObjectAtIndex:indexPath.section];
if ([favs count] == 0) {
[tableView reloadRowsAtIndexPaths:[[NSArray alloc]initWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationFade];
[tableView setEditing:NO animated:YES];
// Remove Edit bar button item
self.navigationItem.rightBarButtonItem = nil;
}
else {
// Animate the deletion from the table.
[tableView deleteRowsAtIndexPaths:[[NSArray alloc]initWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationFade];
}
}
}

Related

UITableViewCell Expandable Crash

I am facing a problem about expandable tableviewcell. It crashes when i try to expand tableviewcell.
I don't understand where app crashes. Please suggest me some solution.
Please Help Me.
My Code:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (appDelegate.array_proj == (id)[NSNull null])
return 0;
else
return [appDelegate.array_proj count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if ([expandedSections containsIndex:section])
{
if ([appDelegate.array_task count]==0)
{
return 0;
}
else
{
NSLog(#"array task count: %d",[appDelegate.array_task count]);
return [appDelegate.array_task count];
}
}
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell ==nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.backgroundColor = [UIColor clearColor];
cell.textLabel.textColor = [UIColor colorWithRed:53.0/255 green:53.0/255 blue:53.0/255 alpha:1.0];
UIImageView *backgroundView = [[UIImageView alloc] initWithFrame:CGRectZero];
cell.backgroundView = backgroundView;
backgroundView.image = [UIImage imageNamed:#"prjctcell_bg.png"];
if (!indexPath.row)
{
objePro = [appDelegate.array_proj objectAtIndex:indexPath.section];
cell.textLabel.text = objePro.projctname;
appDelegate.intForPid=objePro.pojctid;
if ([expandedSections containsIndex:indexPath.section])
{
cell.accessoryView = [DTCustomColoredAccessory accessoryWithColor:[UIColor blackColor] type:DTCustomColoredAccessoryTypeUp];
}
else
{
cell.accessoryView = [DTCustomColoredAccessory accessoryWithColor:[UIColor blackColor] type:DTCustomColoredAccessoryTypeDown];
}
}
else
{
if (appDelegate.array_task != (id)[NSNull null])
{
objePro = [appDelegate.array_proj objectAtIndex:appDelegate.storeAppDelegateIndex];
objeTask = [appDelegate.array_task objectAtIndex:indexPath.section];
cell.textLabel.text = objeTask.taskname;
cell.backgroundView = nil;
cell.accessoryView = nil;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
}
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canCollapseSection:(NSInteger)section
{
return YES;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
objePro = [appDelegate.array_proj objectAtIndex:indexPath.section];
appDelegate.intForPid=objePro.pojctid;
[appDelegate selectTask:appDelegate.intForPid];
if (!indexPath.row)
{
[tblView beginUpdates];
//only first row toggles expand/collapse
[tblView deselectRowAtIndexPath:indexPath animated:YES];
NSInteger sections = indexPath.section;
BOOL currentlyExpanded = [expandedSections containsIndex:sections];
NSInteger rows;
NSMutableArray *tmpArray = [NSMutableArray array];
if (currentlyExpanded)
{
rows = [self tableView:tblView numberOfRowsInSection:sections];
[expandedSections removeIndex:sections];
}
else
{
[expandedSections addIndex:sections];
rows = [self tableView:tblView numberOfRowsInSection:sections];
}
for (int i=1; i<rows; i++)
{
NSIndexPath *tmpIndexPath = [NSIndexPath indexPathForRow:i inSection:sections];
[tmpArray addObject:tmpIndexPath];
}
UITableViewCell *cell = [tblView cellForRowAtIndexPath:indexPath];
if (currentlyExpanded)
{
[tblView deleteRowsAtIndexPaths:tmpArray withRowAnimation:UITableViewRowAnimationTop];
cell.accessoryView = [DTCustomColoredAccessory accessoryWithColor:[UIColor blackColor] type:DTCustomColoredAccessoryTypeDown];
}
else
{
[tblView insertRowsAtIndexPaths:tmpArray withRowAnimation:UITableViewRowAnimationTop];
cell.accessoryView = [DTCustomColoredAccessory accessoryWithColor:[UIColor blackColor] type:DTCustomColoredAccessoryTypeUp];
}
[tblView endUpdates];
}
}
It gives error:
Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-2380.17/UITableView.m:1070
2013-03-20 19:14:00.102 Daily Achiever[2886:c07] * 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 (3) 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, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
Your problem is in these lines of code:
[tblView deleteRowsAtIndexPaths:tmpArray withRowAnimation:UITableViewRowAnimationTop];
and
[tblView insertRowsAtIndexPaths:tmpArray withRowAnimation:UITableViewRowAnimationTop];
The crash that you posted was due to the first one. In these lines, you are trying to insert/delete rows from the table, but your - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section method does not change correspondingly.
It looks like you want to add/remove items from your appDelegate.array_task array whenever you are adding/removing cells from the table (as this is the array from which you are determining the row count).
As a side note, the line:
if ([appDelegate.array_task count]==0) {
return 0;
}
is not doing anything, because you have else return [appDelegate.array_task count] which means that 0 will be returned if [appDelegate.array_task count]==0 anyway.
while adding sections use this code
NSArray *insertIndexPaths = [NSArray arrayWithObjects:
[NSIndexPath indexPathForRow:2 inSection:0],
[NSIndexPath indexPathForRow:3 inSection:0],
nil];
for inserting rows
[tableView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationRight];
if u are adding two sections
[tableView insertSections:[NSIndexSet indexSetWithIndex:indexPath.section + 1] withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView insertSections:[NSIndexSet indexSetWithIndex:indexPath.section + 2] withRowAnimation:UITableViewRowAnimationAutomatic];
same way delete sections
[tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:YES];
[tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section - 1] withRowAnimation:YES];
rows delete
[tableView deleteRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationRight];

UITableView add row below selected row

I had a working tableview where I could double-tap a cell and it would add an 'action' cell below which had four buttons programmed on it.
Today I added alphabetic sections to the tableview and a section index and I can no longer get this functionality to work.
I've added a whole range of NSLogs to the code to try and find the problem and I can't, it seems to be trying to add a row in the same section and one row further down than the cell tapped, so I'm not sure what the problem is. Would anyone have any idea what I'm doing wrong?
If anyone can shed any light on this I would be hugely appreciative. (And apologies if my code is cumbersome or hard to follow, I'm new to this so feel free to suggest what I can improve!)
- (void)viewDidLoad
{
//I start with an array of objects, so I created two arrays; one containing the first letters of each Name, and a list of the number of objects that start with each of those names.
nameIndex = [[NSMutableArray alloc] init];
nameIndexCount = [[NSMutableDictionary alloc]init];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [nameIndex count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (self.actionRowIndexPath) {
//Returns first letter of the section
NSString *alphabet = [nameIndex objectAtIndex:section];
//Returns the number of entries starting with that letter
NSString *numberofRows = [nameIndexCount objectForKey:alphabet];
int intNumberOfRows = ([numberofRows integerValue] + 1);
return intNumberOfRows;
} else {
NSString *alphabet = [nameIndex objectAtIndex:section];
NSString *numberofRows = [nameIndexCount objectForKey:alphabet];
int intNumberOfRows = [numberofRows integerValue];
return intNumberOfRows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"newTableViewCell"];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"newTableViewCell"];
}
//Configure the cell
UIImageView *imageView = [[UIImageView alloc]initWithFrame:cell.frame];
UIImage *image = [UIImage imageNamed:#"LightGrey.png"];
imageView.image = image;
if ([indexPath isEqual:self.actionRowIndexPath]) {
// Four UIButtons coded programmatically
} else {
Contact *p = [[[ContactStore sharedStore]allContacts]objectAtIndex:totalNumberOfRows];
NSString *firstAndLastName = [NSString stringWithFormat:#"%# %#", [p firstName], [p lastName]];
indexPath = [self modelIndexPath:indexPath];
cell.backgroundView = imageView;
// [cell.imageView setImage:smallThumbnailImage];
[cell.imageView setImage:[p thumbnail]];
[[cell textLabel]setBackgroundColor:[UIColor clearColor]];
[[cell textLabel]setText:firstAndLastName];
[[cell detailTextLabel]setBackgroundColor:[UIColor clearColor]];
[[cell detailTextLabel]setText:[p phoneNumber]];
totalNumberOfRows = totalNumberOfRows + 1;
}
return cell;
}
#pragma mark - Action Row Support
-(NSIndexPath *)modelIndexPath: (NSIndexPath *)indexPath
{
if (self.actionRowIndexPath == nil) {
return indexPath;
}
if ([indexPath row] > [self.actionRowIndexPath row]) {
return [NSIndexPath indexPathForRow:([indexPath row] - 1) inSection:indexPath.section];
}
return indexPath;
}
- (void)handleDoubleTap:(UITapGestureRecognizer *)recognizer {
NSLog(#"Double tap");
CGPoint p = [recognizer locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:p];
NSIndexPath *pathToDelete = self.actionRowIndexPath;
_selectedIndexPath = [self modelIndexPath:_selectedIndexPath];
//Is the user deselecting current row?
if (_actionRowIndexPath) {
[self.tableView deselectRowAtIndexPath:_selectedIndexPath animated:NO];
self.selectedIndexPath = nil;
self.actionRowIndexPath = nil;
} else {
//Selecting a new row
self.selectedIndexPath = indexPath;
self.actionRowIndexPath= [NSIndexPath indexPathForRow:([indexPath row] + 1) inSection:[indexPath section]];
}
[self.tableView beginUpdates];
if (pathToDelete) {
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:pathToDelete] withRowAnimation:UITableViewRowAnimationAutomatic];
}
if (self.actionRowIndexPath) {
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:self.actionRowIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
[self.tableView endUpdates];
}
After you get the IndexPath you need to get the IndexPath.row and IndexPath.section and accordingly you need to add the object into your array at the desired index. For example: if you double tap the 2nd row in the 1st section then you need to add the object at index 4 of the array corresponding to the 1st section and then reload table. The cell would be added to the 3rd index of the 1st section.

How do I insert a row at run time into an UITableView on iPhone?

I have created one button with action to add a row to the UITableView at run time but my code is not working. I can see the row animating down, but it's shown animated only on my UITableView row is not added. What can I do in this code to see the row added on cell?
I have 4 sections and I want to add row for 1 section on row 0 and 2 section on row 0:
-(IBAction)add:(id)sender
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
NSArray* path = [NSArray arrayWithObject:indexPath];
// fill paths of insertion rows here
[self.mytableview beginUpdates];
[self.mytableview insertRowsAtIndexPaths:path withRowAnimation:UITableViewRowAnimationBottom];
[self.mytableview deleteRowsAtIndexPaths:path withRowAnimation:UITableViewRowAnimationBottom];
[self.mytableview endUpdates];
[self.mytableview reloadData];
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
NSInteger rows;
if (section==0) {
rows = 4;
//return rowForSectionOne;
//rows=rowForSectionOne++;
}
if (section == 1)
{
rows = 1;
}
return rows;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [mytableview dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
}
if ([indexPath row] == 0 && [indexPath section] == 0)
{
cell.textLabel.text=#"Title";
cell.accessoryView = textField;
titlename=textField.text;
[[cell imageView] setImage:[UIImage imageNamed:#"DetailViewDue.png"]];
NSLog(#"******:%#",titlename);
}
if ([indexPath row] == 1 && [indexPath section] == 0)
{
cell.textLabel.text=#"Tags";
cell.detailTextLabel.text=app.Tags;
[[cell imageView] setImage:[UIImage imageNamed:#"DetailViewTag.png"]];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
if ([indexPath row] == 2 && [indexPath section] == 0)
{
cell.textLabel.text=#"Notes";
cell.detailTextLabel.text=app.Notes;
[[cell imageView] setImage:[UIImage imageNamed:#"DetailViewNote.png"]];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"dd/MM/yyyy"];
fromDate = [[dateFormat stringFromDate:selectionData.fromDateSelected]retain];
if ([indexPath row] == 3 && [indexPath section] == 0)
{
cell.textLabel.text=#"DueDate";
cell.detailTextLabel.text=fromDate;
[[cell imageView] setImage:[UIImage imageNamed:#"DetailViewDue.png"]];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
if ([indexPath row] == 0 && [indexPath section] == 1)
{
cell.textLabel.text=#"Attach";
}
return cell;
}
Well you are doing it right. Lets say when the button is pressed -(IBAction)add:(id)sender is invoked. then compose indexPath with the proper row & section. Here section is 0,1,2,3 (since you have 4 sections -
NSIndexPath *indexPath0 = [NSIndexPath indexPathForRow:0 inSection:0];
NSIndexPath *indexPath1 = [NSIndexPath indexPathForRow:0 inSection:1];
NSIndexPath *indexPath2 = [NSIndexPath indexPathForRow:0 inSection:2];
NSIndexPath *indexPath3 = [NSIndexPath indexPathForRow:0 inSection:3];
//put these indexpaths in a NSArray
[tableView insertRowsAtIndexPaths:array withRowAnimation:UITableViewRowAnimationNone];
This should update the table. No need to do reloadData on the table as you are only adding one row (& not changing the entire table). Also make sure the dataSource has this new added entry per section otherwise your app will crash
You only have to add few lines of code in "cellForRowAtIndexPath" method
if(cell ==nil)
{
cell =[[UITableViewAlloc alloc]initWithStyle.... ]
}
int theRow = indexPath.row;
if(indexPath.section == 1) theRow += 3;
if(indexPath.section == 2) theRow += 5;
if(indexPath.section == 3) theRow += 4;
if(indexPath.section == 4) theRow += 3;
//load the view in it
cell.textLable . text = [<your object> objectAtIndexPath.row];
return cell;
Here you can add rows as many as you want....

Using accessory check mark in a table view

I have a array of 8 items put in a table view.I am using the following code to set the check mark on tap of a row
[[tableView cellForRowAtIndexPath:indexPath]
setAccessoryType:UITableViewCellAccessoryCheckmark];
.But my problem is
1] whenever i tap my first row ,the fifth rows check mark also get showed up.
And
2] when i scroll the table view after checking a row , and return back , checked mark gets disappears.
How to get rid of these problem.
thanks in advance
here is the code
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
// find the cell being touched and update its checked/unchecked image
CellView *targetCustomCell = (CellView *)[tableView cellForRowAtIndexPath:indexPath];
[targetCustomCell checkAction:nil];
if ([arrData count]>0)
{
if ([arrData containsObject:[arrName objectAtIndex:indexPath.row]]) {
[arrData removeObject:[arrName objectAtIndex:indexPath.row]];
[[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryNone];
NSLog(#"data removed");
NSLog(#"arrData%#",arrData);
}
else {
[arrData addObject:[arrName objectAtIndex:indexPath.row]];
[[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark];
NSLog(#"data added");
NSLog(#"tableArray%#",arrData);
}
}
else {
[arrData addObject:[arrName objectAtIndex:indexPath.row]];
[[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark];
NSLog(#"data added");
NSLog(#"arrData%#",arrData);
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *kCustomCellID = #"MyCellID";
CellView *cell = (CellView *)[tableView dequeueReusableCellWithIdentifier:kCustomCellID];
if (cell == nil)
{
cell = (CellView *)[[[CellView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCustomCellID] autorelease];
}
cell.backgroundColor = [UIColor clearColor];
cell.textLabel.font = [UIFont boldSystemFontOfSize:13];
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.textAlignment = UITextAlignmentLeft;
cell.textLabel.text = [arrName objectAtIndex:indexPath.row];
return cell;
}
for your 1) problem you have provide some code
2) problem :
you need to remember your last selected row for that you need to store your last selected index number by :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
selectedIndex = indexPath.row;
[tableView reloadData];
}
and in your
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == selectedIndex)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
cell.accessoryType = UITableViewCellAccessoryNone;
return cell;
}
hope it helps you.

TalbeView cell showing null value

I have created a custom table for the rootViewController of a split view application so that the selected row expands and shows as a sub-table (showing main menu and sub menu ). The first row of the sub-table should show the particular main menu item of the sub-table.I'm fetching the main menu items from another class.
The problem is that the first row for the sub table is showing blank for me.Using NSLog, I checked the value of variable just before assigning it to the cell and even after assigning the value to the cell, i checked the text value in the cell using cell.textLabel.text. I'm getting the value in the console every time, but the row is still blank!!!
Row is showing the value if I'm hard coding it with any value!!!
Note:TableView is showing values for remaining rows.
Anybody can help me?? Thanks in advance...and sorry for my poor English..
EDIT: In the rootViewController:
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
tableView.separatorColor=[UIColor grayColor];
if (sectionopen[indexPath.row]) {
accordianTable *cell1;
cell1=(accordianTable *)[tableView dequeueReusableCellWithIdentifier:#"cell1"];
if (cell1 == nil) {
cell1 = [[[accordianTable alloc] initWithFrame:CGRectZero reuseIdentifier:#"cell1"] autorelease];
}
cell1.selectionStyle=UITableViewCellSelectionStyleNone;
return cell1;
} else {
//tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
static NSString *CellIdentifier = #"CellIdentifier";
// Dequeue or create a cell of the appropriate type.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.selectionStyle = UITableViewCellSelectionStyleGray;
}
// Configure the cell.
cell.textLabel.text=[UIAppDelegate.mainMenu objectAtIndex:indexPath.row];
return cell;
}
}
(void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
accordianTable *acc = [[accordianTable alloc]init];
acc.titl=[UIAppDelegate.mainMenu objectAtIndex:indexPath.row];
[acc.subTable reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
///turn them all off
sectionopen[0]=NO;
sectionopen[1]=NO;
sectionopen[2]=NO;
sectionopen[3]=NO;
///open this one
sectionopen[indexPath.row]=YES;
///animate the opening and expand the row
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
UIViewController *localdetailViewController = nil;
}
In the custom cell class (accordianTable):
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Number of rows is the number of time zones in the region for the specified section.
return [UIAppDelegate.subMenu count]+1;//including title and sub menu
}
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
}
switch (indexPath.row)
{
case 0:
NSLog(#"text is >> %#",titl);
cell.textLabel.text=titl;
NSLog(#"text is >> %#",cell.textLabel.text);
cell.textLabel.textColor=[UIColor whiteColor];
cell.contentView.backgroundColor=[UIColor blackColor];
cell.textLabel.backgroundColor=[UIColor blackColor];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
break;
default:
int Row=indexPath.row;
Row--;
cell.textLabel.text=[UIAppDelegate.subMenu objectAtIndex:Row];
cell.textLabel.textColor=[UIColor orangeColor];
cell.textLabel.textAlignment=UITextAlignmentCenter;
cell.selectionStyle=UITableViewCellSelectionStyleNone;
break;
}
return cell;
}