What is the correct way to remove a row from a UITableView?

I have the following code examples:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { [namesArray removeObjectAtIndex:indexPath.row]; [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; } } 

and

 if ([nameSection count] == 0) { [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; [tableView beginUpdates]; [indexKeys removeObjectAtIndex:section]; [tableView deleteSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationFade]; [tableView endUpdates]; } 

Pay attention to the order .... in the first example, first I delete the object from my array, and then I delete the row from the table.

In the second example, I delete the row from the table, then the section from my array, then the section from the table.

Is this right to do? Or should I remove it from the user interface first and then the arrays?

I ask because I get some users who report these crashes that I cannot reproduce:

NSInternalInconsistencyException - Invalid update: Invalid number of lines in section 1. The number of lines contained in an existing section after updating (0) must be equal to the number of lines contained in this section before

with this stack trace:

 1: libobjc.A.dylib objc_exception_throw 32 2: CoreFoundation [NSException raise:format:] 0 3: Foundation -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] 90 4: UIKit -[UITableView(_UITableViewPrivate) _endCellAnimationsWithContext:] 6042 5: UIKit -[UITableView _updateRowsAtIndexPaths:updateAction:withRowAnimation:] 254 6: UIKit -[UITableView deleteRowsAtIndexPaths:withRowAnimation:] 26 7: Movies _mh_execute_header 253319 8: UIKit -[UITableView(UITableViewInternal) animateDeletionOfRowWithCell:] 84 9: CoreFoundation -[NSObject performSelector:withObject:withObject:] 52 10: UIKit -[UIApplication sendAction:to:from:forEvent:] 62 
+4
source share
2 answers

First you need to update the data model, otherwise the table view will be confused as to what the correct number of rows and sections is.

+3
source

After the table is in edit mode, the table view will then ask for the data source, each row should be editable. If the tableView: canEditRowAtIndexPath: method is implemented, it is called for each row in turn.

 -(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section == 0) { return NO; } return YES; } 

Having established whether it is possible to edit a row, the table view then asks the delegate for the editing style that each row should use:

 -(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { return UITableViewCellEditingStyleDelete; } 

When the Delete button is pressed, tableView sends the message tableView: commitEditingStyle: forRowAtIndexPath: to the data source. It takes three parameters:

1) Link to the tableView itself (in case the data source must distinguish between several table views).

2) the UITableViewCellEditingStyle of the control that was just used - in this case, the UITableViewCellEditingStyleDelete

3) The indexPath object defining this row.

When the data source receives the message commitEditingStyle: forRowAtIndexPath: it needs to do two things:

1) Update the tableViews model by deleting the object represented by the row in the table. Remember that the table itself is just a view, and if we do not actually remove the object from the model, it will appear in the table again the next time the table is reloaded.

2) Send tableView: deleteRowsAtIndexPath: withRowAnimation: a message to the View table so that it updates the table display. In this case, since they are dealing with deletion, it will animate the deleted cell moving to the left, and then move the cells under it to close the gap.

 -(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { [self.tableData removeObjectAtIndex:indexPath.row]; NSArray *indexPathArray = [NSArray arrayWithObject:indexPath]; [tableView deleteRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationAutomatic]; } } 

Theres a range of animation insert and delete table cells to choose from:

  • UITableViewRowAnimationFade - rows disappear and disappear.
  • UITableViewRowAnimationRight - inserted rows are moved to the right; deleted rows are shifted to the right.
  • UITableViewRowAnimationLeft - inserted rows move to the left; deleted rows are shifted to the left.
  • UITableViewRowAnimationTop - inserted rows slide down from the bottom of the line above; deleted lines slide up at the bottom of the line above.
  • UITableViewRowAnimationBottom - inserted rows slide up from the top of the cell below; deleted lines appear to be covered by a line below sliding up.
  • UITableViewRowAnimationNone - just inserted rows; deleted lines just disappear.
  • UITableViewRowAnimationMiddle - cells are inserted and deleted with the effect of the accordion.
  • UITableViewRowAnimationAutomatic - tableView automatically selects the appropriate animation style (available only in iOS 5 and later).

A great book on how to work with tables is here .

+3
source

Source: https://habr.com/ru/post/1485085/


All Articles