从UILabel子视图构造UITableViewCell时如何避免重复行

时间:2011-12-04 14:35:59

标签: uitableview ios5 duplicates subviews

我正在将包含美国州数据的字典元素数组加载到UITableView中,当用户向下滚动到屏幕外项目时,我遇到重复的行 - 第1行在第8行重复,第2行在第9行重复等等。

我已经回顾了以下SO问题,并实施了一些建议(没有成功):

2994472 - 我的UITableView有重复的行

7056578 - 滚动时UITableView重复单元格

UITableViewCell是一个自定义构造,由UILabels创建。这是cellForRowAtIndexPath中的代码。

00    const int ABBREVIATION = 1, STATE = 2 // Declared outside cellForRowAtIndexPath


01    static NSString *CellIdentifier = @"Cell";
02    
03    UILabel *abbreviation, *state;
04    
05    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
06    if (cell == nil) {
07        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault         
08              reuseIdentifier:CellIdentifier];
09        
10        abbreviation = [[UILabel alloc] initWithFrame:CGRectMake(7.0, 1.0, 34.0, 30.0 )];
11        abbreviation.tag = ABBREVIATION; 
12        abbreviation.font = [UIFont fontWithName:@"Helvetica-Bold" size:20.0];
13        abbreviation.textAlignment = UITextAlignmentLeft;
14        abbreviation.textColor = [UIColor blackColor];
15
16        state = [[UILabel alloc] initWithFrame:CGRectMake(42.0, 1.0, 158.0, 30.0)];
17        state.tag = STATE;
18        state.font = [UIFont fontWithName:@"Helvetica-Bold" size:20.0];
19        state.textAlignment = UITextAlignmentLeft;
20        state.textColor = [UIColor blackColor];
21
22        [cell.contentView addSubview:abbreviation];
23        [cell.contentView addSubview:state];
24    
25        [cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton];
26        [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
27    }
28    
29    abbreviation.text = [[self.primaries objectAtIndex:indexPath.row] objectForKey:@"abbreviation"];
30    state.text = [[self.stateInfo objectAtIndex:indexPath.row] objectForKey:@"name"];
31    
32    return cell;

按照2994472中的建议,我修改第27和28行以使用三元运算符。

29   abbreviation.text = [[self.primaries objectAtIndex:indexPath.row] objectForKey:@"abbreviation"] ?
                         [[self.primaries objectAtIndex:indexPath.row] objectForKey:@"abbreviation"] :
                         @"";

30   state.text = [[self.stateInfo objectAtIndex:indexPath.row] objectForKey:@"name"] ?
                  [[self.stateInfo objectAtIndex:indexPath.row] objectForKey:@"name"] : 
                  @"";

这不起作用,重复仍然从第8行开始。

解决问题的方法是在设置标签文本以深入查看实际子视图时引用UILabel标记。

29  ((UILabel *)[cell viewWithTag:ABBREVIATION]).text = [[self.primaries objectAtIndex:indexPath.row] objectForKey:@"abbreviation"];
30  ((UILabel *)[cell viewWithTag:STATE]).text = [[self.primaries objectAtIndex:indexPath.row] objectForKey:@"name"];

以这种方式引用单元格子视图时,UITableView行重复消失。

2 个答案:

答案 0 :(得分:1)

虽然我能够在原始问题中发布解决方案,但我仍然想知道为什么重复的单元格情况首先发生。

做了一些额外的研究,写出状态和缩写值的文本值以及单元格中显示的值。

(A) NSLog(@"%@", state.text);
(B) NSLog(@"%@", ((UILabel *)[cell viewWithTag:STATE]).text);

显示的结果很有趣,并对情况有所了解。

 (A)               (B)
 Iowa              Iowa
 New Hampshire     New Hampshire
 South Carolina    South Carolina
 Florida           Florida
 Nevada            Nevada
 Colorado          Colorado
 Minnesota         Minnesota
 (null)            Iowa
 (null)            New Hampshire
 (null)            SouthCarolina
 (null)            Florida

向上滚动显示其他状态时会显示(null)值。

所以我认为正在发生的是当向下滚动时,第29行和第30行中的原始代码尝试设置两个实例变量的文本值。

29    abbreviation.text = [[self.primaries objectAtIndex:indexPath.row] objectForKey:@"abbreviation"];
30    state.text = [[self.stateInfo objectAtIndex:indexPath.row] objectForKey:@"name"];

但是由于它们已被ARC自动解除引用,它们不再存在,无法设置,并返回null值。但是,包含原始值的单元格将“出列”并与旧数据一起重复使用,从而导致重复出现。

如果我完全偏离这个假设,请告诉我。

答案 1 :(得分:0)

dequeueReusableCellWithIdentifier:返回现有表格视图单元格的情况下,以便跳过if块,未设置abbreviationstate个变量。因此,在这种情况下(当您开始滚动并因此显示重用的单元格时会发生这种情况),abbreviationstate在函数末尾为零,因此重用的单元格标签未按预期更新。您可能需要一个else块,您可以在其中设置缩写和状态变量以指向cell的正确子视图。