插入UITableViewCell无法正常工作

时间:2012-06-21 00:22:11

标签: objective-c ios

有人可以解释我在尝试插入新的UITableViewCell时遇到了什么问题吗?我正在尝试插入自定义UITableViewCell,但它会引发以下错误:'无效更新:第0节中的行数无效。更新后的现有部分中包含的行数(1)必须等于数字在更新(1)之前包含在该部分中的行,加上或减去从该部分插入或删除的行数(插入1个,删除0个)以及加上或减去移入或移出该部分的行数(0搬进来,0搬出去。'

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
if (section == 0)
    return 1;
else if (section == 1)
    return numberOfRows;
return 1;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"EditableCell";

EditableCell *editableCell = (EditableCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (editableCell == nil) {

    editableCell = [[EditableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

_myTextField = [editableCell textFieldCell];

if (indexPath.section == 0){
    [_myTextField setPlaceholder:@"Menu Name"];
    [_myTextField setReturnKeyType:UIReturnKeyNext];
}
else if (indexPath.section == 1){
    [_myTextField setPlaceholder:@"Category"];
    [_myTextField setReturnKeyType:UIReturnKeyNext];
}
else {
    [_myTextField setPlaceholder:@"Category"];
    [_myTextField setReturnKeyType:UIReturnKeyDone];
}

_myTextField.keyboardType = UIKeyboardTypeDefault;
_myTextField.delegate = self;

return editableCell;
}

-(BOOL)textFieldShouldReturn:(UITextField *)textField{

if (textField.returnKeyType == UIReturnKeyNext) {

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:1];
    NSArray *array = [[NSArray alloc] initWithObjects:indexPath, nil];

    [self.tableView insertRowsAtIndexPaths:array withRowAnimation:UITableViewRowAnimationTop];

    numberOfRows = numberOfRows + 1;

    [self.tableView reloadData];
    }     
}

2 个答案:

答案 0 :(得分:7)

您需要确保下面方法中返回的行数现在返回正确的行数。

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

我确定发生的事情是你在插入后返回相同的值,而运行时期望它比调用插入行之前多一个。

更详细一点,MVC术语(模型/视图/控制器)中发生的是:

  1. 您对insertRowsAtIndexPaths的电话请求控制器使用其他行更新视图。
  2. 然后,Controller会进行健全性检查以确定您的总和是否合适,因此它会调用:    tableView:numberOfRowsInSection

    现在控制器知道此方法上次返回的值(在您的情况下为1),并且它还知道您已请求插入行。没有删除调用,所以它希望下次调用这个方法时,值应该是(上次的值+插入行 - 删除的行)= 2

  3. 如果Controller认为你的东西是有序的,那么它会调用cellForRowAtIndexPath(以及其他方法)来获取每个部分中每一行的实际单元格。

  4. 因此,对于您的问题,您需要跟踪模型中的行 - 可能是数组或具有可用行数的ivar。通过在调用insertRowsAtIndexPath之前添加/删除行时更新此值来更新模型,然后在调用tableView:numberOfRowsInSection时返回此值。

    其他提示:

    如果您希望对单元格插入/删除进行动画处理,请将代码更改为以下内容。请注意,不再调用reloadData,而是将插入/重新加载包含在开始/结束更新调用中 - 由于endUpdates调用,动画更新将在reloadSections之后发生。

    NSMutableIndexSet *sectionsToReload = [[NSMutableIndexSet alloc] init];
    [sectionsToReload addIndex:1]; // Add sections as necessary
    
    [self.tableView beginUpdates];
    [self.tableView insertRowsAtIndexPaths:array withRowAnimation:UITableViewRowAnimationTop];
    [self.tableView reloadSections:sectionsToReload withRowAnimation:UITableViewRowAnimationNone];
    [self.tableView endUpdates];
    

    查看WWDC 2010 video from Apple,“掌握表格视图” - 使用insertRowsAtIndexPaths及相关方法解释一切非常好。

    HTH, 拉伸

答案 1 :(得分:0)

尝试插入新单元格后,您的数据源必须包含原始单元格的数量(1)加上您要插入的“额外”单元格(1),总计为2.所以您的tableView:numberOfRowsInSection:必须返回2.

错误消息表明tableView:numberOfRowsInSection:已返回1.

更新您的数据源,以便它返回此“额外”单元格。