UITableView after deleting a row, position of remaining rows - ios

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

Related

UITableCell stays grayed out after deleting and creating new

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

ios delete row from table in ViewController

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!

UITableViewCell delete button not disappearing

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.

App crashs with SIGABRT error when trying to delete a row in tableView

my app crashes when the user tries to delete a row from the UITableView and in the debugger I get the SIGABRT error.
Here is my code for deletion:
- (void) tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[[self displayedObjects] removeObjectAtIndex:[indexPath row]];
// Animate deletion
NSArray *indexPaths = [NSArray arrayWithObject:indexPath];
[[self tableView] deleteRowsAtIndexPaths:indexPaths
withRowAnimation:UITableViewRowAnimationFade];
//[[self tableView] deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]];
}
}
I got help in another question. And the problem is that the object would be deleted from the array but then before deleting the row from the table view , the numberOfRowsInSection is called again which then loads the array from disk again and give the number before the deletion due to a problem in my loading of the array. I put a break point at the numberOfRowsInSection and it is all clear now.
Does your [self displayedObjects]'s item count cover [indexPath row]? For example, your [self displayedObjects] only has 5 item but you want to removeObjectAtIndex:6.
I compared with my code to see where you went wrong.
//Removes From Table
[favorites removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSMutableArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
Favorites is my array. What I think you're going to need to do is change this line:
[[self displayedObjects] removeObjectAtIndex:[indexPath row]];
First, put that line immediately before this one:
[[self tableView] deleteRowsAtIndexPaths:indexPaths
withRowAnimation:UITableViewRowAnimationFade];
And then change self to the name of your array that the table is displaying.
ALSO! VERY IMPORTANT
Make sure the array that the table is displaying is a NSMutableArray NOT a NSArray
With an NSArray, you can't change (add or delete) values. However, with an NSMutableArray you can, so make sure you aren't displaying a NSArray
If I'm not mistaken, you're calling this code:
[[self tableView] deleteRowsAtIndexPaths:indexPaths
withRowAnimation:UITableViewRowAnimationFade];
from within a committed delete event. I believe all you need to do is update your backing store from the "tableView:commitEditingStyle:forRowAtIndexPath:" method. The delete has already been committed. You may also need refresh your table view afterwards also make sure to mark your table view as allowing updates.
Try commenting out all of this code and tell us what happens:
// Animate deletion
NSArray *indexPaths = [NSArray arrayWithObject:indexPath];
[[self tableView] deleteRowsAtIndexPaths:indexPaths
withRowAnimation:UITableViewRowAnimationFade];

ipad this WORKS with breakpoints in and doesn't without... :/

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
this seems to work with a break point on the deleteRowsAtIndexPaths: line, but when I take it out I get EXC_BAD_ACCESS and a crash. NO idea why - its the default code in there for a TableViewController - I added some code and it didn't work. Put break points in and it turned out it was that line, so stripped it right down to the original code and it still doesn't work! :( Argh...
Any ideas?
Thanks
When you delete a row in a tableView numberOfRowsInSection needs to update to return the number of rows before deleting the row minus 1, or else you get this ambiguous crash.

Resources