I created a UITableView with a custom UITableViewCell.
On swipe I delete the last row using
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
I open a new ViewController to provide input for a new cell;
Even if I do a "deselectRowAtIndexPath:indexPath" a new cell is still grayed out (the same way it looks after swiping and the delete buttons shows up - just that it is not moved to the left and no delete button is shown). It only goes back to normal after swiping to delete but canceling it.
I tried several things like
tableView.editing = NO;
[tableView endEditing: YES];
tableView reloadData
tableView reloadInputViews, ...
This problem only happens since iOS 7.
What can I do to have a regular color when creating a new row after deleting all previous rows?
Full code:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[tableView deselectRowAtIndexPath:indexPath animated:FALSE];
[_data removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
Related
In my app I have a Table view with values from a mapkit. I can edit the table, delete the row, but when the app starts over, the same deleted rows are still there....How can I fix this? The code for the editing:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[_locations removeObjectAtIndex:[indexPath row]];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView reloadData];
}
Any tips? Thank you
Load the data from core data using a NSFetchedResultsController.
Implement the delegate function to update your views when change occur.
When you delete something delete enqueue a block to delete it from core data. (if you are using NSPersistentContainer use performBackgroundTask:).
Don't update your views. This will happen automatically because of the delegate callback that you implemented in step 2.
I have an editable UITableView. The user can delete rows. When he does another (non-deletable) row is inserted at the end of the table view. (So the total number of rows in that section remains the same.)
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
// update data model
[self.dataArray removeObjectAtIndex:indexPath.row];
// update table view
[self.tableView beginUpdates];
// delete row
[self.tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:YES];
// insert row at the end of the section
NSIndexPath *indexPathForLastRow = [NSIndexPath indexPathForRow:(kMaxComponents - 1) inSection:0];
[self.tableView insertRowsAtIndexPaths:#[indexPathForLastRow] withRowAnimation:YES];
[self.tableView endUpdates];
}
Works great. However, when I delete the last row of the table view the delete button disappears abruptly with no animation (and too late).
In this case a new row is inserted at the same indexPath where the other one was deleted. What happens is that the animation pushes the old cell to the left while the new cell moves in from the right. But only when the whole animation has finished the red delete button disappears suddenly.
How can I make the delete button disappear smoothly (with an animation)?
I try to manage to delete a row from an UITable which is part on an UIViewController. I use the Edit button in the navigation bar. Hitting it will put the table rows in edit mode. But when a delete button in a row is pressed I get an error ...'Invalid update: invalid number of rows in section 0…. when using the following:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
[self.tableView setEditing:editing animated:YES];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSMutableArray *work_array = [NSMutableArray arrayWithArray:self.inputValues];
[work_array removeObjectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
What do I miss here? The Apple documentation seems to be outdated somehow.
Thanks
The problem is simple. You are not updating your data model properly before deleting the row from the table.
All you do is create some new array and delete a row from that. That's pointless. You need to update the same array used by the other data source methods such as numberOfRowsInSection:.
The issue you are having is that you are not directly updating your table's data source. You first create a completely new array called work_array based on your data source (I'm assuming it's self.inputValues) and then you remove an item from it, and then try to delete a row, but your tableView's data source still contains the item you intended to remove.
All you need to do is ensure that self.inputValues is a mutable array and directly remove the object at the index for that array, like this:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.inputValues removeObjectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
I hope that helps!
I'm using a UISegmentedControl to switch a UITableView between two datasets (think favorites and recents). Tapping the segmented control reloads the tableview with the different data set.
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:anim];
When the user swipes to delete a row it works fine. HOWEVER when the user switches datasets via the segmented control, the DELETED CELL gets re-used without altering it's appearance (i.e. the red 'DELETE' button is still there and the row content is nowhere to be seen). This appears to be the opposite problem that most people are seeing which is the delete button not appearing.
This is the delete code:
- (UITableViewCellEditingStyle) tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleDelete;
}
- (void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
if ([self.current isEqualTo:self.favorites])
{
Favorite *fav = self.favorites[indexPath.row];
NSMutableArray *mut = [self.favorites mutableCopy];
[mut removeObjectAtIndex:indexPath.row];
self.favorites = mut;
self.current = self.favorites;
[self.tableView deleteRowsAtIndexPaths:#[indexPath]
withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
}
The tableview is set to single select, and self.tableView.editing == NO. I have also tried using [self.tableView reloadData] and deleting/inserting the difference in rows from one dataset to the next. Neither works.
The UITableViewCell I'm using supplies no backgroundView or selectedBackgroundView
[EDIT]
Segmented Control Value Changed:
- (IBAction)modeChanged:(id)sender
{
if (self.listMode.selectedSegmentIndex == 1)
{
self.current = self.favorites;
}
else
{
self.current = self.recents;
}
// Tryin this:
[self.tableView reloadData];
// Tried this:
// [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
}
// Only 1 Section per table
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
return [self.current count];
}
Oh for the love of...
I wasn't calling [super prepareForReuse]; in my UITableViewCell subclass.
UGH.
I ran into the same thing: to "delete" a custom UITableViewCell, I was removing it from the table and putting it onto another list, which the user could then display in a modal view when they have regrets and want to put it back. In iOS7 (but not iOS6), the cells so moved had the big ugly "DELETE" button still on them, despite calling setEditing:NO and so on. (And in addition, the rest of the cell content was not drawn at all, even though inspecting the cells in the debugger showed that all the subpanes were still there.)
Unlike Stephen above, I hadn't overridden prepareForReuse, so that wasn't the problem. But it was related: in my case, the cells weren't created with a reuse identifier:
self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
And per the docs, "If the cell object does not have an associated reuse identifier, this method is not called." But apparently, in iOS7 at least, it should be.
So the solution, in my case, was to explicitly call this [cell prepareForReuse] on each cell as I loaded it into the new table.
I have created a table view in iOS and implemented delete row functionality. Everything is working. I have one doubt,
Consider the following case,
Suppose the table has 15 rows, and if I delete row no 10. Sometimes the cells from the top (1-9) animate from top to bottom to the position of row no 10. Sometimes the cells from the bottom(11-15) animate to the top. This occurs in random.
This is the code for deleting
- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#">>> Entering %s <<<", __PRETTY_FUNCTION__);
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[[self contents] removeObjectAtIndex:[indexPath row]];
NSArray *indexPathsToRemove = [NSArray arrayWithObject:indexPath];
[tableView deleteRowsAtIndexPaths:indexPathsToRemove withRowAnimation:UITableViewRowAnimationAutomatic];
}
NSLog(#"<<< Leaving %s >>>", __PRETTY_FUNCTION__);
}
And between this is tutorial I am following
You can download the project from this link.
Is there anyway to control this behaviour.
Thanks in advance
You can control it with
withRowAnimation:UITableViewRowAnimationAutomatic
There are various option available
UITableViewRowAnimationBottom
UITableViewRowAnimationFade
UITableViewRowAnimationRight
...
Actual method is:
[mainTableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic];