如何阻止UITableView单元格覆盖内容?

zar*_*don 11 objective-c uitableview custom-cell tableviewcell ios

我正在使用UITableView,我注意到我的tableview中的单元格在滚动时逐渐变得更大胆,它覆盖了内容,我想要阻止它,但是看不到我出错的地方.

在我的UITableView上,出于某种原因,当我滚动tableview的内容时,会搞乱手动创建的UILabel.

我需要手动UILabel,因为我需要稍后使用自定义单元格.

当我上下滚动时,标签逐渐变得更大胆,更大胆; 它们总是重叠,有时甚至会影响较低的行(甚至在它们处于视口之前).

如果我继续这样做,细胞内容就会变得难以理解.

仅当backgroundColor未设置为时才会发生这种情况clearColor.

我曾尝试[cellLabel setClearsContextBeforeDrawing:YES];[self.tableView setClearsContextBeforeDrawing:YES]; 没有效果.

如果我使用cell.textLabel.text那么问题似乎消失了.

代码和图像示例如下.

  // Simple table view
    - (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    {
        static NSString *CellIdentifier = @"Cell";

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

        // Configure the cell...
        //[self configureCell:cell atIndexPath:indexPath];


        NSString *txt = @"Product";


        //cell.textLabel.text = txt;
        cell.selectionStyle = UITableViewCellSelectionStyleNone;

        UIView *cellView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, cell.frame.size.height)];

        UILabel *cellLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 120, 35)];
        [cellLabel setText:txt];
        [cellLabel setFont:[UIFont boldSystemFontOfSize:12]];
        [cellLabel setBackgroundColor:[UIColor clearColor]];

        [cellView addSubview:cellLabel];
        [cellLabel release];
        [cell.contentView addSubview:cellView];
        [cellView release];


        return cell;
    }


Image follows;


![image of uitableview][1]


  [1]: http://i.stack.imgur.com/5lNy6.png


// Edit to include context

I am using a dictionary to display the contents of the UITableViewCells.

I have attempted to do the following;

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

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

            [self configureCell:cell atIndexPath:indexPath];
        } // end if


        // Configure the cell...
        //
       // Moved to inside the cell==nil        

        return cell;
    }

-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{

    // Get the txt from the Dictionary/Plist... *removed due verboseness*

    UILabel *cellLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 120, 35)];
    [cellLabel setText:txt];
    [cellLabel setFont:[UIFont boldSystemFontOfSize:12]];
    [cellLabel setBackgroundColor:[UIColor clearColor]];

    [cell.contentView addSubview:cellLabel];
    [cellLabel release];
}
Run Code Online (Sandbox Code Playgroud)

这虽然它解决了覆盖问题 - 它会导致问题 - 它会使标签重复出现在完全随机的位置 - 以下只是一个示例,其他字段和标签也会重复.

见下图;

在uitableview中重复标签

A-L*_*ive 17

    // cell reuse
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Run Code Online (Sandbox Code Playgroud)

返回给你已经使用过的单元格,它已经有了一个UILabel子视图,你在它上面添加另一个.将添加子视图放在该部分

   if (cell == nil) { //cell initialization
Run Code Online (Sandbox Code Playgroud)

在单元初始化根据需要编辑子视图,例如,您可以通过标签访问它们.

  • @zardon当你使用`dequeueReusableCellWithIdentifier`重复使用单元格时,未添加一次添加的UILabel,您有责任更新子视图内容或将其外观重置为默认值(如UILabel的setText:@"").否则,先前配置的子视图可能会显示在重用的单元格中(如果您有条件地更改单元格内容). (2认同)

fel*_*bus 6

您每次都将标签添加到同一个重复使用的单元格中,这就是它变得更大胆的原因.当您使用dequeueReusableCellWithIdentifier时,您正在抓取已经在屏幕上显示的单元格,这是正确的操作,但您已经在其上放置了标签.由于标签每次都会在相对于单元格的相同位置,以及相同的颜色等.(唯一的动态元素将是文本),您应该只将其设置为一次.

我首选的解决方案是创建一个具有所需属性的自定义单元格.所以在这种情况下,你会创建

@interfacce MyCustomCell : UITableViewCell
    @property (nonatomic) UILabel *cellLabel;
@end
Run Code Online (Sandbox Code Playgroud)

给它一个属性UILabel*cellLabel,除了在MyCustomCell.m的init中设置标签文本之外,执行上面的所有代码,用self替换任何单元格实例,例如:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];

    if (self)
    {
        self.cellLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 120, 35)];
        [self.cellLabel setText:txt];
        [self.cellLabel setFont:[UIFont boldSystemFontOfSize:12]];
        [self.cellLabel setBackgroundColor:[UIColor clearColor]];
    }

    return self;
}
Run Code Online (Sandbox Code Playgroud)

现在在你的cellForRowAtIndexPath中使用MyCustomCell,你检查cell == nil,你可能还要检查单元格标签:

if(cell == nil || cell.cellLabel == nil)
Run Code Online (Sandbox Code Playgroud)

以完全相同的方式初始化它:

cell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
Run Code Online (Sandbox Code Playgroud)

现在,您需要做的就是设置:

cell.cellLabel.text = ....;
Run Code Online (Sandbox Code Playgroud)

你在cellForRowAtIndexPath中的代码更清晰,内存效率更高,并且你不会得到你的错误.

请记住在接口构建器中将单元格设置为MyCustomCell类型.