选择自定义构建的 UITableViewCell 时 UILabel 文本的错误行为:文本与先前加载的标签混合或覆盖

发布于 2024-10-05 16:29:40 字数 3412 浏览 0 评论 0原文

几天来我一直在寻找这个问题的解决方案......但找不到有类似问题的人或适合我的解决方案。在这一点上,我什至不确定我做错了什么,因为我已经阅读和分析了许多示例代码,并且我几乎 100% 确定我正在按照应该的方式这样做......

无论如何,它来了:

我有我向其中显示自定义构建的 UITableViewCell 的 UITableView,这是我创建它们的位置:

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

    NSDictionary *myDictionary = [myArray objectAtIndex:indexPath.row];

    UITableViewCell *cell = [tableView
                 dequeueReusableCellWithIdentifier:CellIdentifier];  

    if (cell == nil)
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero 
                               reuseIdentifier: CellIdentifier] autorelease];


    CGRect textViewRect = CGRectMake(10.0, 0.0, 250, 25);
    UILabel *textView = [[UILabel alloc] initWithFrame:textViewRect];

    textView.text = [myDictionary objectForKey:@"name"];
    textView.font = [UIFont systemFontOfSize:12.0];
    textView.textColor = [UIColor blackColor];
    textView.highlightedTextColor = [UIColor whiteColor];
    textView.textAlignment = UITextAlignmentRight;

    [cell.contentView addSubview:textView];
    [textView release];


    CGRect imageRect = CGRectMake(270.0, 15, 16, 16);
    UIImageView *icon = [[UIImageView alloc] initWithFrame:imageRect];

    icon.image = [myDictionary objectForKey:@"color-icon"];
    icon.highlightedImage = [myDictionary objectForKey:@"gray-icon"];

    [cell.contentView addSubview:icon];
    [icon release];
}

如您所见,非常标准的东西...然后,当我单击其中一个单元格时,会加载另一个视图而不是表格。 到目前为止,一切都很好,但是当我回到该表视图并且它必须重新加载时,问题就开始了......

顺便说一下,我已将其添加到委托方法中,这样单元格就不会保持选中状态:

- (void)tableView:(UITableView *)tableView
                 didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    // [...] a lot more code here 
}

当我单击时用鼠标在模拟器中的我的单元格上按住鼠标,单元格会按预期保持选中状态(在设备本身上也是如此),这就是为什么我得到:

[图片 1]

UILabel 文本完全混合了!屏幕截图实际上是表格的最后一个单元格,重叠的文本是第一个单元格的文本。第一个的行为是类似的,如果我继续单击它,它将显示与最后一个单元格的 UILabel 文本混合的相同行为。我猜测这是由于 dequeueReusableCellWithIdentifier 的工作方式造成的(可能是 FILA 队列)。

当然,我尝试解决这个问题并发现了一些非常奇怪的东西。

如果我不单击,单元格是完美的,没有错误,显示正确的文本等:

[图片 2]

然后我尝试稍微弄乱我的 UILabel 的参数。我添加了这个:

textView.backgroundColor = [UIColor clearColor];

当我这样做时,一旦表格重新加载,我什至不需要突出显示单元格来查看搞砸的行为:

[图片3]

我要摆脱的唯一方法总是实例化一个新单元而不是使单元出列的问题...

UITableViewCell *cell = [tableView
                 dequeueReusableCellWithIdentifier:CellIdentifier];   
if (cell == nil)
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero 
                               reuseIdentifier: CellIdentifier] autorelease];

被替换为:

UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero 
                               reuseIdentifier: CellIdentifier] autorelease];

但是,当然,由于内存泄漏,这不会长期有效...

另外,值得注意的是,我有确切的此应用程序中另一个视图中的另一个 UITableView 具有相同的行为...另一个自定义单元格更复杂,更多标签,更多图像等,但所有标签都表现出相同的行为。这个更复杂的表视图由导航控制器管理,因此没有像第一个那样的自定义加载/卸载...

这就是我所拥有的,我找不到解决方案...请帮助!

啊,这真的很烦人...我是新人,所以我无法发布图片...:( 您可以在以下链接中查看引用的图像: https ://skitch.com/aponsin/rne9k/fullscreen.png-100-layer-3-rgb-8

亚历克斯

I have been looking for a solution to this issue for a few days now... and cannot find someone with a similar problem or a solution that would work for me. At this point I am not even sure that I am doing something wrong, as I have read and analyzed many sample code and I am almost 100% sure that I am doing this the way it should...

Anyway here it comes:

I have a UITableView to which I display custom built UITableViewCell, here is where I create them:

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

    NSDictionary *myDictionary = [myArray objectAtIndex:indexPath.row];

    UITableViewCell *cell = [tableView
                 dequeueReusableCellWithIdentifier:CellIdentifier];  

    if (cell == nil)
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero 
                               reuseIdentifier: CellIdentifier] autorelease];


    CGRect textViewRect = CGRectMake(10.0, 0.0, 250, 25);
    UILabel *textView = [[UILabel alloc] initWithFrame:textViewRect];

    textView.text = [myDictionary objectForKey:@"name"];
    textView.font = [UIFont systemFontOfSize:12.0];
    textView.textColor = [UIColor blackColor];
    textView.highlightedTextColor = [UIColor whiteColor];
    textView.textAlignment = UITextAlignmentRight;

    [cell.contentView addSubview:textView];
    [textView release];


    CGRect imageRect = CGRectMake(270.0, 15, 16, 16);
    UIImageView *icon = [[UIImageView alloc] initWithFrame:imageRect];

    icon.image = [myDictionary objectForKey:@"color-icon"];
    icon.highlightedImage = [myDictionary objectForKey:@"gray-icon"];

    [cell.contentView addSubview:icon];
    [icon release];
}

So as you can see, pretty standard stuff... Then when I click on one of the cell, another view gets loaded instead of the table.
Until now, everything is fine, but then when I come back to that table view and that it has to reload the problem starts...

By the way I have added this to the delegate methods so the cells never stay selected:

- (void)tableView:(UITableView *)tableView
                 didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    // [...] a lot more code here 
}

When I clicked on my cell in the simulator with the mouse and keep it down the cell stays selected as expected (same way on the device itself) and this is why I get:

[Image 1]

The UILabel Text is totally mixed up ! The screenshot is actually of the last cell of the table and the overlapping text is the one of the first cell. And the behavior on the first is similar, if I maintain the click on it, it will show the same behavior mixing up with the UILabel text of the last cell. I am guessing that is is due to the way the dequeueReusableCellWithIdentifier works (probably a FILA queue).

Of course I tried to work around that and found some really weird stuff.

If I don't click the cells are perfect, no bugs, the correct text is displayed etc:

[Image 2]

Then I tried to mess up a little bit with the parameters of my UILabel. I added this:

textView.backgroundColor = [UIColor clearColor];

And when I do this, as soon as the table reload, then I don't even need to highlight the cell to see the screw up behavior:

[Image 3]

The only way I was about to get rid of the problem to always instantiate a new cell rather than dequeueing one...

UITableViewCell *cell = [tableView
                 dequeueReusableCellWithIdentifier:CellIdentifier];   
if (cell == nil)
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero 
                               reuseIdentifier: CellIdentifier] autorelease];

was replaced by:

UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero 
                               reuseIdentifier: CellIdentifier] autorelease];

But of course this won't work on the long term because of the memory leak...

Also, it is to be noted that I have the exact same behavior for another UITableView in another view somewhere in this App... The other custom cell is more complex, more labels, more images, etc, but all the label exhibit the same behavior. And this more complex Table View is managed by a Navigation Controller, so no custom loading / unloading like the first one...

That's all I have, and I can't find a solution... please help !

Arghh this is really annoying... I am new so I cannot post images... :(
Here is a link where you can see the referenced images: https://skitch.com/aponsin/rne9k/fullscreen.png-100-layer-3-rgb-8

Alex

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

孤单情人 2024-10-12 16:29:40

问题是您每次重复使用单元格时都会创建新标签并将其添加到单元格中。要解决此问题,您必须仅在创建单元格时创建标签:

if (cell == nil){
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero 
                               reuseIdentifier: CellIdentifier] autorelease];

    CGRect textViewRect = CGRectMake(10.0, 0.0, 250, 25);
    UILabel *textView = [[UILabel alloc] initWithFrame:textViewRect];
    textView.tag = kLabelTag;
    textView.font = [UIFont systemFontOfSize:12.0];
    textView.textColor = [UIColor blackColor];
    textView.highlightedTextColor = [UIColor whiteColor];
    textView.textAlignment = UITextAlignmentRight;

    [cell.contentView addSubview:textView];
    [textView release];


    CGRect imageRect = CGRectMake(270.0, 15, 16, 16);
    UIImageView *icon = [[UIImageView alloc] initWithFrame:imageRect];

    icon.image = [myDictionary objectForKey:@"color-icon"];
    icon.highlightedImage = [myDictionary objectForKey:@"gray-icon"];

    [cell.contentView addSubview:icon];
    [icon release];
}

之后,您可以使用您分配的标签属性从单元格获取标签:

UILabel *textView = (UILabel*)[cell.contentView viewWithTag:kLabelTag];
textView.text = [myDictionary objectForKey:@"name"];

相同的逻辑也适用于设置图标图像视图(如果它在不同的单元格中有所不同

)查看标准 UITableViewCell 已经提供的组件(取决于其单元格样式) - 那里已经有 UIImageView 和 UILabels,您可以为它们设置自定义属性并使用它们,而无需创建额外的组件

The problem is that you create new label and add it to cell each time cell is being reused. To fix that you must create your label only when your cell is created:

if (cell == nil){
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero 
                               reuseIdentifier: CellIdentifier] autorelease];

    CGRect textViewRect = CGRectMake(10.0, 0.0, 250, 25);
    UILabel *textView = [[UILabel alloc] initWithFrame:textViewRect];
    textView.tag = kLabelTag;
    textView.font = [UIFont systemFontOfSize:12.0];
    textView.textColor = [UIColor blackColor];
    textView.highlightedTextColor = [UIColor whiteColor];
    textView.textAlignment = UITextAlignmentRight;

    [cell.contentView addSubview:textView];
    [textView release];


    CGRect imageRect = CGRectMake(270.0, 15, 16, 16);
    UIImageView *icon = [[UIImageView alloc] initWithFrame:imageRect];

    icon.image = [myDictionary objectForKey:@"color-icon"];
    icon.highlightedImage = [myDictionary objectForKey:@"gray-icon"];

    [cell.contentView addSubview:icon];
    [icon release];
}

And after that you can get your label from cell using tag property you've assigned:

UILabel *textView = (UILabel*)[cell.contentView viewWithTag:kLabelTag];
textView.text = [myDictionary objectForKey:@"name"];

same logic also applies to setting up your icon imageview if it varies in different cells

Also have a look at components standard UITableViewCell already provides (depending on its cell style) - there's already UIImageView and UILabels there and you can set your custom properties to them and use them without creating extra components

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文