4

我有以下代码示例:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

    if (editingStyle == UITableViewCellEditingStyleDelete) 
    {
        [namesArray removeObjectAtIndex:indexPath.row];

        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];        
    }   
}

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

注意顺序....在第一个示例中,我首先从数组中删除对象,然后从 tableview 中删除该行。

在第二个示例中,我从 tableview 中删除行,然后从我的数组中删除部分,然后从 tableview 中删除部分。

这是做事的正确顺序吗?或者我应该先从 UI 中删除它,然后再从数组中删除它?

我问的原因是因为我有一些用户报告了这些我似乎无法重现的崩溃:

NSInternalInconsistencyException - 无效更新:第 1 节中的行数无效。更新 (0) 后现有节中包含的行数必须等于该节中包含的行数之前

使用此堆栈跟踪:

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

2 回答 2

3

After the table is in editing mode, the table view will then ask the data source whether each row should be editable. If the tableView:canEditRowAtIndexPath: method is implemented, this 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 a row can be edited, the table view then asks the delegate which editing style each row should use:

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

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

1) A reference to the tableView itself (in case the data source needs to distinguish between a number of tableViews).

2) The UITableViewCellEditingStyle of the control that’s just been tapped—in this case, UITableViewCellEditingStyleDelete

3) An indexPath object locating the row in question.

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

1) Update the tableView’s model by deleting the object represented by the row in the table. Remember that the table itself is just a view, and unless we actually delete the object from the model, it will reappear in the table the next time the table gets reloaded.

2) Send the tableView:deleteRowsAtIndexPath:withRowAnimation: message to the tableView so that it updates the table display. In this case, because we’re dealing with a Delete, it will animate the deleted cell sliding off to the left, and then move the cells below it up 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];
        }
    }

There’s a range of table cell insertion and deletion animations to choose from:

  1. UITableViewRowAnimationFade - Rows fade in and out.
  2. UITableViewRowAnimationRight - Inserted rows slide in from the right; deleted rows slide out to the right.
  3. UITableViewRowAnimationLeft - Inserted rows slide in from the left; deleted rows slide out to the left.
  4. UITableViewRowAnimationTop - Inserted rows slide down from the bottom of the row above; deleted rows slide up toward the bottom of the row above.
  5. UITableViewRowAnimationBottom - Inserted rows slide up from the top of the cell below; deleted rows appear to be covered by the row below sliding up.
  6. UITableViewRowAnimationNone - Inserted rows simply appear; deleted rows simply disappear.
  7. UITableViewRowAnimationMiddle - Cells are inserted and deleted with an accordion-style effect.
  8. UITableViewRowAnimationAutomatic - The tableView automatically chooses an appropriate animation style (available only in iOS 5 and later).

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

于 2013-06-07T17:35:15.583 回答
3

您应该首先更新您的数据模型否则表格视图会混淆正确的行数和节数。

于 2013-06-07T16:50:02.663 回答