Smooth reload of uitableview data when rows are deleted - iphone

I am trying to reload a uitableview when it scrolls to the bottom of the screen. I delete the first few rows and add more rows to the bottom. Before the news rows are added to the uitableview's data source, i call the [tableview reloaddata] method. This is because i want the tableview to display the row which were previously visible on it.
It reloads the data correctly but there is a sudden jerk in the tableview. It flashes which doesn't give a nice user experience. So my question is
How to update the uitableview
when few rows from the top are
deleted without having the
jerking/flashing effect?
The current visible row should be retained in the refreshed view also.
Any ideas? There are no crashes as i update the data source correctly.
TIA,
Praveen S

delete the data from the data source in tableView delegate.
-(void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *key = [keys objectAtIndex:indexPath.section];
NSMutableArray *nameSection =[names objectForKey:key];
int itemID=item.ID;
if ([nameSection count]==1) {
[self.keys removeObjectsInArray:[NSArray arrayWithObject:key]];
[tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationFade];
}
else {
[nameSection removeObjectAtIndex:indexPath.row];
[self.names setValue:nameSection forKey:key];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
}
}
check this too

Related

UITableView commitEditingStyle without deleting cell

I have small problem with my conception of deleting rows in UITableView. After user deletes a row i do not want to fire:
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
Instead I want to change edited cell text and background without hiding it. My approach works quite well:
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSMutableArray *previous_points = [self.trip_arrayOfAllPoints mutableCopy];
[previous_points removeObjectAtIndex:indexPath.row];
self.trip_arrayOfAllPoints = nil;
self.trip_arrayOfAllPoints = [[NSMutableArray alloc] initWithCapacity:[previous_points count]];
self.trip_arrayOfAllPoints = [previous_points mutableCopy];
self.trip_arrayOfAllPointsEDITED = [[NSMutableArray alloc] initWithCapacity:[previous_points count]];
self.trip_arrayOfAllPointsEDITED = [previous_points mutableCopy];
//[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
self.trip_isArrayOfAllPointsEDITED = YES;
}
But after deleting a row it does not commit animation of dissapearing "DELETE" label on current cell. Is there a way around "Apple way" of deleting rows?
EDIT - I've worked it out
It's pretty simple and plain. Just replace deleteRowsAtIndexPaths with:
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
After this "delete" animation disappears and cell is still in it's place.
You mean that "Delete" button stays, even if you pressed it? On my iOS 5.1 emulator after
pressing "Delete" with empty:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
"Delete" button disappears.
I'm using this code and it's working fine
//self.selectedMessageIndex is NSIndexPath object declared in header file
//self.attachments is a NSMutableArray Object
[self.attachments removeObjectAtIndex:self.selectedMessageIndex.row];
[tblvAttachmentsList deleteRowsAtIndexPaths:[NSArray arrayWithObject:self.selectedMessageIndex]
withRowAnimation:UITableViewRowAnimationLeft];
[tblvAttachmentsList reloadData];
self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation:.Automatic)
This is going to remove the delete button with a nice animation. Invoke, when you know you are not going to delete the row:
func tableView(tableView: UITableView, commitEditingStyle editingStyle:UITableViewCellEditingStyle, forRowAtIndexPath indexPath:NSIndexPath) {
if (editingStyle == UITableViewCellEditingStyle.Delete) {
//An action happens here. If it was successful, page is refreshed
//If the action fails, cell stays. I am showing an error and:
self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation:.Automatic)
}
}

Change an image in a UITableViewCell without reloading cell

I'm writing an iPhone app with a UITableView as the primary user interface. Each section consists of two rows, a header and the body. When the user clicks on the header, I remove the second row by changing the numberOfRowsInSection value:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
cbwComponent *comp = [_componentController objectInListAtIndex:section];
if([comp hasContentsView] && !comp.contentsHidden){
return 2;
}else
return 1;
}
When the user selects the header, I'm using the following code:
comp.contentsHidden = YES;
[self.tableView beginUpdates];
NSArray *deleteIndexPaths = [[NSArray alloc] initWithObjects:[NSIndexPath indexPathForRow:1 inSection:indexPath.section], nil];
[self.tableView deleteRowsAtIndexPaths:deleteIndexPaths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
It's working great, with a nice smooth fade effect. The problem is, I'm trying to add an indicator in the header cell (row 0) that changes when it's clicked on. To change that image I have to refresh the top row as well as the second row, which makes the transition look bad (well, not nearly as smooth). Is there a way to change the image in a UITableViewCell without refreshing the cell?
Thanks
EDIT: I figured it out! You can maintain the smooth transition as long as you reload that first row before you make the change to the second row. It has to be called inside of [tableView beginUpdates];
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:[[NSArray alloc] initWithObjects:[NSIndexPath indexPathForRow:0 inSection:indexPath.section], nil] withRowAnimation:UITableViewRowAnimationNone];
...
[self.tableView endUpdates];
Did the trick.
You could also subclass a tableview cell and implement a view transition in it that can be called from your view controller. You could then call that without having to reload the cell.
[(YourCustomCell*)[tableView cellForRowAtIndexPath:indexPathOfYourCell] fadeInIndicator];

Refreshing UITableview Section to One With Different Number of Rows

I've recently been working with a UITableView. It is dynamically populated once, then when a user selects an option, I want the list to change to a new one. I'm working with a grouped table with 3 sections and as you click on the rows the three groups need to be repopulated with a varying number of new rows. While my code works fine when there is the same number of rows in the new section as old, it crashes when that number changes. Interestingly though, it will wait to crash until it attempts to draw one of the cells that was there previously (the tableView still thinks the section has the old number of rows, tries to draw the cell that is no longer in my model object, and so I think it crashes because it's referencing a value in the new array that doesn't exist.
It crashes here:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:#"MyCell"];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"MyCell"];
}
if (indexPath.section==2){
//CRASH BELOW
cell.textLabel.text = [NSString stringWithFormat:#"%#", (NSString *)[[[[storyArray objectAtIndex:pageNumber]getChoices] objectAtIndex:(unsigned long)indexPath.row]objectAtIndex:0]] ;
}
return cell;
}
The function I use to reload the table is here:
-(void)changePage:(int)pageChangeNumber{
NSLog(#"The page change! Changing to: %#",[[storyArray objectAtIndex:pageChangeNumber]getTitle]);
pageHeader.text=[[storyArray objectAtIndex:pageChangeNumber] getTitle];
pageBody.text=[[storyArray objectAtIndex:pageChangeNumber] getBody];
[myTableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
[myTableView reloadSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationFade];
[myTableView reloadSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationFade];
[myTableView reloadData];
pageNumber=pageChangeNumber;
NSLog(#"Page Change Done");
}
I've also changed the numberofRowsInSection to be dynamic...
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
NSLog(#"Recounting Rows");
if (section==2){
return [[[storyArray objectAtIndex:pageNumber]getChoices] count];
} else {
return 0;
}
}
Any ideas on how I can get this working when the number of rows per section changes?
Thanks!
I don't know what crash you're getting, but I ran into crashes if the numberOfSectionsInTableView: or tableView:numberOfRowsInSection: methods returned different numbers of rows while the table was restructuring itself.
For example, UITableView calls those methods many times while it is redrawing (including during animations). In my backend, some of the values were changing during animation.
I had to take special care to synchronize those values before changing the UITableView
Before you update your table view's data and call reloadSections you need to first call [myTableView beginUpdates] and once you're done [myTableView endUpdates]

How to delete row from table view?

I have a table view, data were retrieved from database and display in the table rows.
I have a remove button at the top navigation bar from removing table row.
When button is tapped, a red circle delete icon will appear.
After I select delete, it gave me and error call "Program received signal SIGABRT" at the [tableViewDelete rows......]
This is my code.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
Object = [array objectAtIndex:indexPath.row];
[ClassA ClassAMethod:[appDelegate getDBPath] :Object.ID];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
How do I remove a row from the table view?
Does anybody have any ideas or has anybody else achieved anything similar?
Thanks
I assume this line:
[ClassA ClassAMethod:[appDelegate getDBPath] :Object.ID];
deletes your object from database, while table is filled from some array instance - you need to delete an object from that array as well to maintain data integrity (array must be NSMutableArray instance):
Object = [array objectAtIndex:indexPath.row];
[ClassA ClassAMethod:[appDelegate getDBPath] :Object.ID];
// Add the following line
[array removeObjectAtIndex:indexPath:row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
try this code in editing delegate method of tableview:--
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[[self displayedObjects] removeObjectAtIndex:[indexPath row]];
// Animate deletion
NSArray *indexPaths = [NSArray arrayWithObject:indexPath];
[[self tableView] deleteRowsAtIndexPaths:indexPaths
withRowAnimation:UITableViewRowAnimationFade];
}
i hope this can solve your problem

UITableView "swipe to delete" function freezes

I can't figure out why my tableView isn't updating after I tap the delete button.
Once I click it, the table view "freezes". If I click another row, so that the tableview goes to another level of the hierarchy and click back, I can see that the item has been deleted and everything works fine.
Here is my code:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
//[tableView beginUpdates];
if (editingStyle == UITableViewCellEditingStyleDelete)
{
// Do whatever data deletion you need to do...
[tableView beginUpdates];
NSManagedObject *obj = (NSManagedObject *)[entityArray objectAtIndex:indexPath.row];
[managedObjectContext deleteObject:obj];
NSError *error;
[managedObjectContext save:&error];
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:YES];
[self viewWillAppear:YES];
}
//[tableView endUpdates];
}
Any input on this problem would be appreciated.
Thanks.
Found same issue and stumbled upon this thread. But the reason for the tableview freeze issue was different in our case.
For the sake of posterity:
The UITableViewCell which goes into Edit mode to display the "insert" or "delete" buttons should never have its userInteractionEnabled property set to "NO".
By correcting this, the same tableview freezing issue was fixed for us.
I can't see a call to [tableView endUpdates] matching the [tableView beginUpdates] that is at start of the if.
Could it be for this reason that your table freezes?