checkboxes in uitableview are giving errors - iphone

I have 2 sections and I am trying to make it so when you click the checkbox of a cell in one of the sections, it goes to the other section (ex: section 1->section 2)
here is some relevant code of mine:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell"];
if (!cell)
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"UITableViewCell"];
if([indexPath section] == 0){
cell.textLabel.text = [[[taskArray objectAtIndex:[indexPath row]] taskName] uppercaseString];
cell.imageView.image = [UIImage imageNamed:#"checkboxtry2.png"];
} else if ([indexPath section] == 1) {
cell.textLabel.text = [[[completedArray objectAtIndex:[indexPath row]] taskName] uppercaseString];
cell.imageView.image = [UIImage imageNamed:#"checkboxtry2selected.png"];
}
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(handlechecking:)];
[cell.imageView addGestureRecognizer:tap];
cell.imageView.userInteractionEnabled = YES;
return cell;
}
-(void)handlechecking:(UITapGestureRecognizer *)t{
CGPoint tapLocation = [t locationInView:self.tableView];
NSIndexPath *tappedIndexPath = [self.tableView indexPathForRowAtPoint:tapLocation];
NSIndexPath *newIndexPath = nil;
if (tappedIndexPath.section == 0) {
[completedArray addObject:[taskArray objectAtIndex:tappedIndexPath.row]];
[taskArray removeObject:[taskArray objectAtIndex:tappedIndexPath.row]];
newIndexPath = [NSIndexPath indexPathForRow:tappedIndexPath.row inSection:1];
}
else {
[taskArray addObject:[completedArray objectAtIndex:tappedIndexPath.row]];
[completedArray removeObject:[completedArray objectAtIndex:tappedIndexPath.row]];
newIndexPath = [NSIndexPath indexPathForRow:tappedIndexPath.row inSection:0];
}
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:tappedIndexPath] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
}
I have two arrays: taskArray which handles objects in section 0 and completedArray which handles objects in section 1.
I am getting the error * Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'

2 things.
You are adding gesture recognisers repeatedly to your table view cells even when they have been re-used and already have one.
Also in your gesture recogniser target you could do something like this which might be more reliable:
UITableViewCell *cell = [[t.view superview] superview];
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];

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 Accessorytype Checkmark Reset Code

I know how to handle with cellaccesory type check mark, here I want a button to Uncheck the entire tablecell which are checkmarked? Here my code, can any one please help me to code
- (void)viewDidAppear:(BOOL)animated
{
UIBarButtonItem *rest = [[UIBarButtonItem alloc]initWithTitle: #"RESET" style: UIBarButtonItemStyleBordered target: self action: #selector(uncheckCells)];
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
[toolbar setItems:[NSArray arrayWithObjects:rest,flexibleSpace,flexibleSpace,home,nil]];
[self.navigationController.view addSubview:toolbar];
[self.tableView reloadData];
}
Here the code for my functions
-(void)uncheckCells//unchecking function
{
[self.tableView reloadData];//HERE WHAT SHOULD I DO
}
-(void)hom
{
[self dismissModalViewControllerAnimated:YES];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [ar objectAtIndex:indexPath.row];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
if(cell.accessoryType==UITableViewCellAccessoryCheckmark)
{
cell.backgroundColor=UIColorFromRGB(0xd05818);
cell.detailTextLabel.text=#"packed";
cell.detailTextLabel.textColor=[UIColor cyanColor];
}
else
{
cell.backgroundColor=[UIColor whiteColor];
cell.detailTextLabel.text=#"";
}
return cell;
[self.tableView reloadData];
}
(void) deselect
{
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
}
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView reloadData];
[tableView deselectRowAtIndexPath:indexPath animated:NO];
printf("User selected row %d\n", [indexPath row] + 1);
if ([[tableView cellForRowAtIndexPath:indexPath] accessoryType] == UITableViewCellAccessoryCheckmark)
{
[[tableView cellForRowAtIndexPath:indexPath]setAccessoryType:UITableViewCellAccessoryNone];
}
else
[[tableView cellForRowAtIndexPath:indexPath]setAccessoryType:UITableViewCellAccessoryCheckmark];
[self performSelector:#selector(deselect) withObject:nil afterDelay:0.0f];
[tableView reloadData];
}
If you're doing checkmarks on didSelectRowAtIndexPath: method. A reloadData will work for you.
For eg.
Say you have a button with selector uncheckCells
-(void)uncheckCells
{
[self.tableView reloadData];
}
This should work you.
EDIT: add cell.accessoryType = UITableViewCellAccessoryNone; in your if (cell == nil) condition.
Or do this:
-(void)uncheckCells
{
for (int section = 0, sectionCount = self.tableView.numberOfSections; section < sectionCount; ++section) {
for (int row = 0, rowCount = [self.tableView numberOfRowsInSection:section]; row < rowCount; ++row) {
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:section]];
cell.accessoryType = UITableViewCellAccessoryNone;
cell.accessoryView = nil;
}
}
}
I hope it will work.
From reading your code, it looks like you are setting the checkmark on the table view itself.
What you should really be doing is storing whether or not a cell has a check mark in your data source, and using this information in the tableView:cellForRowAtIndexPath: method to display a checkmark or not.
And your deselect method should be going through you datasource and unsetting whatever marker you have there that says whether or not your tableview has a check mark.
That way, when you scroll a tableview, or just call [tableView reloadData]; your datastore will be used to decide whether or not to display a checkmark or not.

UITableView deleteRowsAtIndexPath crash when delete last record

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];
}
}
}

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....

IPhone reloadRowsAtIndexPaths weird animation

Hi I'm new to this iPhone dev and I have a question about reloadRowsAtIndexPaths. When the user taps one cell, it will expand showing buttons underneath it and tapping it again closes the cell. This works fine when opening and closing cell one at a time, but I have this weird animation when tapping cells in sequence like cell one is tapped, cell 2 is tapped the animation gets weird. Please see the video to fully understand the situation and sorry for the low quality.
http://www.youtube.com/watch?v=R28Rmti9wPQ
and here's the code for reloading the cells
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
selectedIndexPath = indexPath;
//close the selected cell if it's open
if(selectedIndex == indexPath.row)
{
selectedIndexPath = nil;
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
selectedIndex = -1;
selectedIndexPath = indexPath;
return;
}
//this will reload the previously open cell to avoid it from being recycled
if(selectedIndex >= 0)
{
NSIndexPath *previousPath = [NSIndexPath indexPathForRow:selectedIndex inSection:0];
selectedIndex = indexPath.row;
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:previousPath] withRowAnimation:UITableViewRowAnimationFade];
}
//now reload the selected cell
if(selectedIndexPath != nil && [selectedIndexPath isEqual:indexPath]) {
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
and here's the code for creating the cellForRowAtIndexPath.
if(selectedIndexPath != nil && [selectedIndexPath isEqual:indexPath]) {
selectedIndex = indexPath.row;
static NSString *CustomCellIdentifier = #"CustomCell";
CustomCell *customCell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier: CustomCellIdentifier];
if (customCell == nil) {
customCell = [[[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CustomCellIdentifier] autorelease];
}
customCell.locationLabelOutlet.text = [usgsFeeds objectAtIndex:[indexPath row]];
customCell.dateLabelOutlet.text = [pubDateArr objectAtIndex:[indexPath row]];
float thisMag;
thisMag = [(NSNumber *)[magnitudeArr objectAtIndex:[indexPath row]] floatValue];
customCell.magnitudeImageOutlet.image = [self imageForMagnitude:thisMag];
[customCell setSelectionStyle:UITableViewCellSelectionStyleNone];
return customCell;
}
else{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
locationLabel = [[[UILabel alloc] initWithFrame:CGRectMake(10, 3, 225, 20)] autorelease];
locationLabel.tag = kLocationLabelTag;
locationLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size:14.0];
locationLabel.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview:locationLabel];
//and all other views for the cell....
Try reloading both the cell you just selected and the one that was selected before.
This is how I solved a similar problem in my own app.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if( selectedPath == indexPath)
{
return;
}
showNutritionInfo = NO;
NSIndexPath *oldSelectedPath = selectedPath;
selectedPath = indexPath;
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, oldSelectedPath,nil] withRowAnimation:UITableViewRowAnimationFade]; }