iPhone:向Cell ContentView添加子视图会在滚动时覆盖单元格文本

时间:2011-06-16 11:06:08

标签: iphone uitableview addsubview

我在我的实现中使用了Cell.ContentView来自定义单元格内容。它工作正常,但唯一的问题是,当我有很多单元格并且我上下滚动它们时,单元格内容会被覆盖到单元格中,只是隐藏后跟可见。假设我先滚动第一个单元格然后再将其取下,最后一个单元格的内容会被第一个单元格覆盖!!

我已经对此进行了足够的调试,但无法找到确切的解决方案。我尝试检查Cell.ContentView.SubViews计数,如果它为0则只添加其他子视图。直到我上下滚动它才会显示任何单元格内容但是一旦内容出现,它就不会覆盖......有点奇怪.. !!我还确保我正在使用正确的重复使用单元格。以下是我的代码,它将子视图添加到单元格的内容视图中。请让我知道如何摆脱这个问题。

P.S:不要担心我所做的变量和计算。假设它返回正确的值。 :)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    NSInteger totalAvailableSpace = IPHONE_DISPLAY_WIDTH - iconSize - accesorySize - 10;
    NSInteger lableHeight = [[cellDetails objectForKey:@"TableItemTextFontSize"] intValue] * 2 + 10;

    UILabel *textLabel = nil;
    textLabel = [[[UILabel alloc] initWithFrame:CGRectMake(iconSize+12, self.tableCellHeight/2 - lableHeight/2, totalAvailableSpace * 0.8, lableHeight)] autorelease];
    textLabel.numberOfLines = 2;
    textLabel.lineBreakMode = UILineBreakModeWordWrap;
    textLabel.textAlignment = UITextAlignmentLeft;
    textLabel.text = [cellDetails objectForKey:@"TableItemMainText"];
    if ([textLableColor scanHexInt:&hex]) {
        textLabel.textColor = UIColorFromRGB(hex);
    }
    textLabel.font = [UIFont fontWithName:[cellDetails objectForKey:@"TableItemTextFontName"] size:[[cellDetails objectForKey:@"TableItemTextFontSize"] intValue]]; 
    [cell.contentView addSubview:textLabel];
    textLabel.backgroundColor = [UIColor clearColor];

    lableHeight = [[cellDetails objectForKey:@"TableItemDetailTextFontSize"] intValue] * 2 + 10;
    UILabel *detailTextLabel = nil;
    detailTextLabel = [[[UILabel alloc] initWithFrame:CGRectMake(iconSize+10+totalAvailableSpace * 0.8+5, self.tableCellHeight/2 - lableHeight/2, totalAvailableSpace * 0.2 - 10, lableHeight)] autorelease];
    detailTextLabel.numberOfLines = 2;
    detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
    detailTextLabel.textAlignment = UITextAlignmentLeft;
    detailTextLabel.text = [cellDetails objectForKey:@"TableItemDetailText"];
    if ([detailTextLableColor scanHexInt:&hex]) {
        detailTextLabel.textColor = UIColorFromRGB(hex);
    }
    detailTextLabel.font = [UIFont fontWithName:[cellDetails objectForKey:@"TableItemDetailTextFontName"] size:[[cellDetails objectForKey:@"TableItemDetailTextFontSize"] intValue]];
    [cell.contentView addSubview:detailTextLabel];
    detailTextLabel.backgroundColor = [UIColor clearColor];

    return cell;
}

感谢。

5 个答案:

答案 0 :(得分:6)

这是因为玩具一遍又一遍地向你的细胞添加视图。

您只应在创建单元格时添加它们,并在重复使用单元格时设置标签。

您可以为标签设置标签,以便之后可以设置文本。下面的代码可以解决这个问题

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        if(style == UITableViewCellStyleValue1)
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        else
            cell = [[[UITableViewCell alloc] initWithStyle:style reuseIdentifier:CellIdentifier] autorelease];


        NSInteger totalAvailableSpace = IPHONE_DISPLAY_WIDTH - iconSize - accesorySize - 10;
        NSInteger lableHeight = [[cellDetails objectForKey:@"TableItemTextFontSize"] intValue] * 2 + 10;

        UILabel *textLabel = nil;
        textLabel.tag = 1;
        textLabel = [[[UILabel alloc] initWithFrame:CGRectMake(iconSize+12, self.tableCellHeight/2 - lableHeight/2, totalAvailableSpace * 0.8, lableHeight)] autorelease];
        textLabel.numberOfLines = 2;
        textLabel.lineBreakMode = UILineBreakModeWordWrap;
        textLabel.textAlignment = UITextAlignmentLeft;
        textLabel.text = [cellDetails objectForKey:@"TableItemMainText"];
        if ([textLableColor scanHexInt:&hex]) {
            textLabel.textColor = UIColorFromRGB(hex);
        }
        textLabel.font = [UIFont fontWithName:[cellDetails objectForKey:@"TableItemTextFontName"] size:[[cellDetails objectForKey:@"TableItemTextFontSize"] intValue]]; 
        [cell.contentView addSubview:textLabel];
        textLabel.backgroundColor = [UIColor clearColor];

        lableHeight = [[cellDetails objectForKey:@"TableItemDetailTextFontSize"] intValue] * 2 + 10;
        UILabel *detailTextLabel = nil;
        detailTextLabel.tag = 2;
        detailTextLabel = [[[UILabel alloc] initWithFrame:CGRectMake(iconSize+10+totalAvailableSpace * 0.8+5, self.tableCellHeight/2 - lableHeight/2, totalAvailableSpace * 0.2 - 10, lableHeight)] autorelease];
        detailTextLabel.numberOfLines = 2;
        detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
        detailTextLabel.textAlignment = UITextAlignmentLeft;
        detailTextLabel.text = [cellDetails objectForKey:@"TableItemDetailText"];
        if ([detailTextLableColor scanHexInt:&hex]) {
            detailTextLabel.textColor = UIColorFromRGB(hex);
        }
        detailTextLabel.font = [UIFont fontWithName:[cellDetails objectForKey:@"TableItemDetailTextFontName"] size:[[cellDetails objectForKey:@"TableItemDetailTextFontSize"] intValue]];
        [cell.contentView addSubview:detailTextLabel];
        detailTextLabel.backgroundColor = [UIColor clearColor];

    } else {

        UILabel *textLabel = (UILabel *)[cell viewWithTag:1];
        textLabel.text = [cellDetails objectForKey:@"TableItemMainText"];

        UILabel *detailTextLabel = (UILabel *)[cell viewWithTag:2];
        detailTextLabel.text = [cellDetails objectForKey:@"TableItemDetailText"];

    }

    return cell;
}

答案 1 :(得分:4)

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];

if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
}

确保dequeueReusableCellWithIdentifierreuseIdentifier应为nil

现在它会起作用!!

答案 2 :(得分:2)

将所有单元格UI内容放在if(cell == nil){uilabel,uilabel或anythingUI related} ...因为ui在创建cel时应该只调用一次

答案 3 :(得分:2)

要明确的是,您的问题是,当您将单元格滚动到视图中时,您经常会看到新单元格的文本被写在刚刚滚动到屏幕外的单元格的顶部?

问题是dequeueReusableCellWithIdentifier:没有“清理”单元格(它调用prepareForReuse,但就是这样),所以所有旧的子视图仍然存在。如果要重用单元格,则不应每次都重新创建这些子视图。相反,只需调整从dequeueReusableCellWithIdentifier:返回的单元格上现有子视图的属性,并仅在新分配的单元格上创建新的子视图。子类化UITableViewCell可以帮助解决这个问题,既可以提供属性/ ivars来保存对这些子视图的引用,也可以通过将子视图的创建和更新移动到适当的方法来更好地组织代码。或者你可以通过传递nil作为重用标识符来重用单元格。

在您向上和向下滚动之前它没有显示任何内容的最可能的原因是新创建的单元格可能具有框架提供的文本字段和图像视图,如果框架确定该文本字段和图像视图,则可以将其删除你实际上并没有使用它们。

答案 4 :(得分:0)

在iOS5中{@ 1}}已弃用。您应该使用UILineBreakModeWordWrap代替。

这会将您的代码更改为NSLineBreakByWordWrappingdetailTextLabel.lineBreakMode = NSLineBreakByWordWrapping