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)
}
}
Related
I want to remove a specific cell from a UITableView
I found deleteRowsAtIndexPaths:withRowAnimation:
I tried to change the cell.frame to 0,0,0,0
I tried to .hidden = YES it
nothing works for me.
Any ideas?
Thank you!
Try adding the begin and end calls for editing:
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:deletePaths withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
Alternatively, if you are working with an underlying data source, remove the object from the datasource and call [tableView reloadData];
Use this method to remove the cell from your table view and hand to hand remove the same objects from your array by which you are showing data on tableview.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[yourArray removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
}
[tableView reloadData];
}
Hope this will help you..
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
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
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?
I'm having a UITableView with alternating colored UITableViewCells. And the table can be edited: rows can be reordered and deleted. How do I update the cells alternating background color, when the rows get reordered or deleted?
I'm using this to draw the alternating colored cells:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if ([indexPath row] % 2) {
// even row
cell.backgroundColor = evenColor;
} else {
// odd row
cell.backgroundColor = oddColor;
}
}
But this method is not being called when a row gets reordered or deleted. And I can't call [tableView reloadData] from the following method, because it crashes the app in an infinite loop:
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
// Move the object in the array
id object = [[self.list objectAtIndex:[fromIndexPath row]] retain];
[self.list removeObjectAtIndex:[fromIndexPath row]];
[self.list insertObject:object atIndex:[toIndexPath row]];
[object release];
// Update the table ???
[tableView reloadData]; // Crashes the app in an infinite loop!!
}
Does anybody have a pointer or a best practices solution to deal with the issue of reordering alternating colored cells?
Thanks
Used a delayed call to perform the reload if you can't call from that method:
[tableView performSelector:#selector(reloadData) withObject:nil afterDelay:0.0f];
It waits until after your current method is finished before it calls reload.
No needs to use third-party objects or reload/refresh the whole dataSource. Just use the right tools in your swiss knife:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if(editingStyle == UITableViewCellEditingStyleDelete) {
//1. remove your object
[dataSource removeObjectAtIndex:indexPath.row];
//2. update your UI accordingly
[self.myTableView beginUpdates];
[self.myTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
[self.myTableView endUpdates];
//3. obtain the whole cells (ie. the visible ones) influenced by changes
NSArray *cellsNeedsUpdate = [myTableView visibleCells];
NSMutableArray *indexPaths = [[NSMutableArray alloc] init];
for(UITableViewCell *aCell in cellsNeedsUpdate) {
[indexPaths addObject:[myTableView indexPathForCell:aCell]];
}
//4. ask your tableview to reload them (and only them)
[self.myTableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
}
}
Reload is too heavyweight; I've written AltTableViewController that just changes background color of cells and it should work faster.
I took all the UITableViewCell subviews from the tableview and sorted that array based on cells frame.origin.y so they were back in the proper order. Then I looped through changing the background color based on the index == 0 || index % 2 == 0 re-coloring them. Seems to work better than reloading the tableView as that was causing the animation to jerk. Worked for me at 1:25 AM
[tableView reloadData] will get your table backgrounds back in the swing of things. Your other option is to swap the background colors of the all visible cells from the indexPath of the lower index in the move on up to the highest in visibleCells.
This works nice. Start the pattern at the last index rather than the first. That way each cell always retains it's background:
if (dataSource.count - indexPath.row) % 2 == 0 {
cell.backgroundColor = UIColor.grayColor()
} else {
cell.backgroundColor = UIColor.whiteColor()
}
I tried the other solutions, but wasn't completely satisfied. This solution is not a hack and doesn't even add another line of code.
If you're using swift and NSFetchedResultsController:
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.endUpdates()
//for the alternate colours
self.tableView.reloadRows(at: tableView.indexPathsForVisibleRows!, with: .fade)
}