为什么UITableViewCell没有正确重新加载?

时间:2012-03-15 07:12:25

标签: objective-c ios uitableview

我正在将一堆国家/地区加载到一个表中并允许用户删除。这些行直接对应于countries数组,使用objectAtIndex:indexPath.row并将删除按钮的标记设置为相同的索引。

当我删除前几行时没关系,但之后错误的行被删除,应用程序崩溃。

以下是我创建行的方法:

- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
NSString *currentText;

// fill in country cell content 
if ([tableView tag] == 400) {
    cell = [tableView dequeueReusableCellWithIdentifier:@"SettingsCountryCell"];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                      reuseIdentifier:@"SettingsCountryCell"];
        NSLog(@"is nil"); 
    } // it´s never nil

    currentText = [arrSelectedCountries objectAtIndex:indexPath.row];
    int currentRow = indexPath.row;

    UILabel *countryLabel = (UILabel *)[cell viewWithTag:401];
    countryLabel.text = currentText;

    // create button
    UIButton *countryButton = (UIButton *)[cell viewWithTag:402];

    [countryButton setTag:currentRow];
    [countryButton setTitle:[NSString stringWithFormat:@"row%d", currentRow] 
                   forState:UIControlStateNormal];
    NSLog(@"%@ - tag %d - title %@ - button tag %d", 
          currentText, 
          currentRow, 
          countryButton.titleLabel.text,
          countryButton.tag);

    // on load: Bulgaria - tag 2 - title row2 - button tag 2
    // after one deletion (and ever after): 
    //      Bulgaria - tag 1 - title (null) - button tag 0 

    [countryButton addTarget:self 
                      action:@selector(removeCountry:)
            forControlEvents:UIControlEventTouchUpInside]; 

}    

以下是我删除它们的方式(即国家/地区):

- (void)removeCountry:(UIButton *)countryButton
{
// removed country
NSString *currentText = [arrSelectedCountries objectAtIndex:countryButton.tag];

NSLog(@"removed country %@ at tag %d", currentText, countryButton.tag);

// ok: removed country All CEE Countries at tag 0
// ok: removed country Bulgaria at tag 0
// not ok: removed country Czech Republic at tag 1

// add to picker selection and remove from selected
[arrCountries addObject:currentText];
[arrSelectedCountries removeObject:currentText];

// refresh picker and country table
[countryPicker reloadAllComponents];

[countryTable reloadData];

[countryTable reloadSections:[NSIndexSet indexSetWithIndex:0] 
            withRowAnimation:UITableViewRowAnimationFade];

// position table and elements below it
[self repositionForCountryChange]; 
}

首先,该表显示:row0,row1,row2等

删除几次后:row1,row2,row3等。

一旦发生这种情况,标签就不再与标签正确对应。当我在克罗地亚点击删除时,删除标记为第1行的按钮,NSLog说:

removed country Czech Republic at tag 1

...虽然克罗地亚的删除按钮现在显示为row2,但克罗地亚行并未删除。

为什么我从NSLog获得:

title (null) - button tag 0 

...当我在表格中看到有标题时,removeCountry可以访问按钮标签,虽然不正确?

1 个答案:

答案 0 :(得分:0)

您已设置带有标记的按钮,以便您将其标识为单元格中的子视图(402),然后更改标记,以便标识标记所在的行。单元格被重复使用,没有标记402 的视图,因此您的按钮仍然标识有其原始行的标记号。

您使用标签有两个目的。理想情况下,不要使用它们,因为它们很脆弱,并且不会使您的代码可读。

  • 创建UITableViewCell子类并使用outlet
  • 标识其子视图
  • 使用我描述的here方法识别按下按钮的行,这比标记更灵活,并且如果删除行则继续工作。