cellLabel.text 的内容似乎在随机单元格中覆盖自身

Posted

技术标签:

【中文标题】cellLabel.text 的内容似乎在随机单元格中覆盖自身【英文标题】:Content of cellLabel.text seems to be overwriting itself in random cells 【发布时间】:2010-09-11 00:40:26 【问题描述】:

我有一个 UITableView,它是从一个包含 79 个条目的 NSMutable 数组中填充的。当我运行我的应用程序并向下滚动表格时,一个单元格中似乎有多个条目。它似乎发生在桌子下方大约一个屏幕高度。

例如:

数组中的一个对象是@"Dog",另一个是@"Cat"。在一个单元格中,您可以在 cellLabel 文本中看到 Cat 和 Dog。

初始化单元格的代码

// Customize the appearance of table view cells.
- (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];
        cell.accessoryType = UITableViewCellAccessoryNone;
    

    // Configure the cell...

    UILabel *cellLabel = [[[UILabel alloc] initWithFrame:cell.frame] autorelease];
    cellLabel.text = [symptomsArray objectAtIndex:indexPath.row];
    cellLabel.textColor = [UIColor blackColor];
    cellLabel.backgroundColor = [UIColor clearColor];
    cellLabel.opaque = NO;
    [cell.contentView addSubview:cellLabel];
    cell.contentView.backgroundColor = [UIColor colorWithRed:(214.0/255) green:(215.0/255.0) blue:(217.0/255) alpha:1.0];

    return cell;

【问题讨论】:

【参考方案1】:

保持简单。

如果你只有几个条目,为什么不在加载之前分配一个单元格数组,直接从数组里面加载单元格对象:

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

 return [arrayOfCells objectAtIndex:indexPath.row]; //already allocated one single time at the beginning

    

不再有 dequeueReusableCellWithIdentifier..

保持简单!

【讨论】:

谢谢。这最终成为对我来说最好的方式。【参考方案2】:

子视图相对于其父视图的边界定位。因此,例如,如果您希望cellLabel 位于内容视图的左上角,则需要将其原点设置为 (0, 0)。您正在使用单元格的框架,它相对于表格视图的左上角。

当您向下滚动时,UITableView 正在重复使用旧单元格,并且您正在为这些单元格添加其他标签。这些单元格的框架的原点从表格视图顶部偏移一两个屏幕,因此您将新标签定位在单元格的实际边界之外。以下是解决方法。

static int CellLabelTag = 12345;

if (cell == nil) 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    cell.accessoryType = UITableViewCellAccessoryTypeNone;

    UILabel *cellLabel = [[[UILabel alloc] initWithFrame:cell.contentView.bounds] autorelease];
    cellLabel.tag = 585493;
    [cell.contentView addSubview:CellLabelTag];


UILabel *cellLabel = (UILabel *)[cell viewWithTag:CellLabelTag];
cellLabel.text = // your text here
// blah blah blah configuration
return cell;

【讨论】:

【参考方案3】:

那是因为你每次都在添加标签 如果你真的需要那个新的 UiLabel,那么将它添加到你拥有的 if 语句中,并将它的文本从 if 中更改出来

为了有效地做到这一点,你可能不得不继承 UITableViewCell

希望对你有帮助

【讨论】:

【参考方案4】:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
if (cell == nil) 
 cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];

确保“dequeueReusableCellWithIdentifier”和“reuseIdentifier”应为“nil”

现在它可以工作了!!

【讨论】:

您是否建议使用reuseIdentifier:nil 是最佳做法?【参考方案5】:

Alex 的答案是最好的答案,很多人没有意识到这种情况正在发生,特别是如果他们没有使用 ClearColor 背景作为标签,在这种情况下你永远不会看到这种覆盖。

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

@interfacce MyCustomCell : UITableViewCell
    @property (nonatomic) UILabel *cellLabel;
@end

给它一个属性 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:cell.frame];
        self.cellLabel.textColor = [UIColor blackColor];
        self.cellLabel.backgroundColor = [UIColor clearColor];
        self.cellLabel.opaque = NO;
        [self..contentView addSubview:cellLabel];
        self.contentView.backgroundColor = [UIColor colorWithRed:(214.0/255) green:(215.0/255.0) blue:(217.0/255) alpha:1.0];
    

    return self;

现在在您的 cellForRowAtIndexPath 中使用 MyCustomCell,您可以在其中检查单元格 == nil,您可能还需要检查单元格标签:

if(cell == nil || cell.cellLabel == nil)

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

cell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

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

cell.cellLabel.text = [symptomsArray objectAtIndex:indexPath.row];

你在 cellForRowAtIndexPath 中的代码更干净,内存效率更高,而且你不会得到你的错误。

记得在界面生成器中将单元格设置为 MyCustomCell 类型。

【讨论】:

以上是关于cellLabel.text 的内容似乎在随机单元格中覆盖自身的主要内容,如果未能解决你的问题,请参考以下文章

如何根据带有自动调整大小的传入数据在集合视图单元格中添加随机内容(UIKit 元素)?

带有 UILabel 和随机文本长度的 UITableViewCell 高度问题

随机化表格单元格

UITableViewCell 内容视图不填充单元格

16进制转10进制,是否要用strtoul函数

如何在 TableView Cell 中设置随机图像