iOS:CellForRowAtIndexPath单元格变得混乱 [英] iOS: CellForRowAtIndexPath cells are getting mixed up

查看:66
本文介绍了iOS:CellForRowAtIndexPath单元格变得混乱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先要说我看过以下问题:

Going to start off by saying I've seen these questions:

iOS:UITableView在滚动速度过快时会混合数据

(自定义)UITableViewCell滚动后会发生混淆

在UITableView中滚动后混合的项目

第一个和最后一个似乎与我的问题非常相关,但是我可以肯定地说,我对每个部分都有逻辑,以确定应该在单元格(数据)中显示什么,但是它们仍然混杂在一起.

The first and last seemed very relevant to my problem, however I am fairly certain that I have logic for each section to determine what should appear in the cell (the data), and yet they still get mixed up.

以下是相关代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Note: the if (cell == nil) thing is no longer required in iOS 6
static NSString *CellIdentifier = @"Cell";

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


if (closestRenter != nil)
{
    NSLog(@"CLOSEST RENTER!");
    [self setupCellsWithClosestRenterCell:cell atIndexPath:indexPath];
}
else
{
    NSLog(@"NO CLOSEST RENTER");
    [self setupCellsWithNoClosestRenterCell:cell atIndexPath:indexPath];
}

if (indexPath.section == 0)
{
    for (UIView *view in cell.contentView.subviews)
    {
        NSLog(@"WHAT THE HECK");
        [view removeFromSuperview];
    }
}

return cell;

}

此处的相关信息:

1)ClosestRenter不为零...存在.因此,else子句永远不应执行……就是这种情况.

1) ClosestRenter is NOT nil... it exists. So the else clause should never be executed... and that is the case.

2)在代码内:

[self setupCellsWithClosestRenterCell:cell atIndexPath:indexPath];

有一个简单的方法:

if (indexPath.section == 0)
{
    cell.textLabel.text = @"PLACE HOLDER";
}
else
{
    // Populate the cell with data. (creates a view (with controller etc) and loads it into the cell)
}

3)始终有2个部分.

3) There are 2 sections at all times.

问题在于,第0部分(第一部分)应该只包含那个占位符字符串.第1节应包含我的自定义子视图(在单元格中,它确实如此).

The problem is that section 0 (the first section) should have nothing more than that placeholder string. Section 1 should contain my custom subviews (in cells, which it does).

第0部分最初只有一个占位符字符串,但是一旦我向下滚动(该部分不再可见)并向上滚动(快速),它有时会在第1部分中出现一个看似随机的单元格...哎呀?如何?我不愿意指责单元重用,但在这一点之外,我真的不知道这是什么.

Section 0 initially has just the placeholder string, however once I scroll down (and the section is no longer visible) and scroll back up (quickly) it sometimes has a seemingly random cell from section 1 in there... what the heck? How? I'm reluctant to blame cell reuse but at this point outside of something really silly I don't know what it is.

这里令人不安的是,第0节中的单元格(那里只有1行)没有子视图.但是,当我快速上下滚动时,它会得到一个(显然是从第1节开始),然后我收到"What the HECK"日志消息...

The disturbing part here is that the cell in section 0 (there is only 1 row there) has no subviews. But when I scroll up and down fast it gets one (from section 1 apparently) and then I get the "WHAT THE HECK" log messages...

值得一提的是,使用for循环(一个带有heck消息内容的循环)确实可以解决问题(因为它删除了不需要的子视图),但是必须有一种更好的方法.现在感觉不对.

It should be worth mentioning that with the for loop (the one with the what the heck messages) does solve the problem (as it removes the unwanted subviews) but there has to be a better way. It feels wrong right now.

有什么想法吗?

(随意将其标记为重复项,但我可以肯定这里还有其他事情要做).

(Feel free to mark this as a duplicate, but I'm fairly certain there is something else going on here).

谢谢.

推荐答案

因此,经过一番挫折和仔细的分析,我发现了为什么细胞混合在一起了.

So after a little bit of frustration, and careful analysis I found out why the cells were getting mixed up.

我对单元复用(尤其是标识符)的假设是问题所在.

My assumption about cell reuse (particularly with the identifiers) was the problem.

以前我是这样做的:

static NSString *CellIdentifier = @"Cell";

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

这是一件很棒的事情,但是有一个关键问题.从技术上讲,下面的所有单元都是相同的...分配完所有单元(不是nil)后,系统无法确定要重用的单元,无论它位于哪个部分.

Which is great and all, however there is a critical problem. All cells were technically the same underneath... after they are all allocated (not nil) the system could not determine which cell to reuse no matter what section it was.

这意味着任何单元格都可以从队列中取出,并保留在任何位置(尽管我进行了检查以确保第1部分的内容进入第1部分,而第0部分的内容(假租房者)仍留在了队列中)在那里).

This meant that any cell could be grabbed from the queue, with whatever it had in it, and stuck anywhere (despite my checks to make sure section 1 stuff went in section 1, and section 0 stuff (the fake renter) stayed in there).

解决方案:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Note: the if (cell == nil) thing is no longer required in iOS 6
static NSString *CellIdentifier1 = @"Cell";
static NSString *CellIdentifier2 = @"Cell2";

UITableViewCell *cell;

if (indexPath.section == 0)
{
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier1];
    }
    else
    {
        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
    }

}
else
{
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier1];
    }
    else
    {
        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
    }
}


if (closestRenter != nil)
{
    NSLog(@"CLOSEST RENTER!");
    [self setupCellsWithClosestRenterCell:cell atIndexPath:indexPath];
}
else
{
    NSLog(@"NO CLOSEST RENTER");
    [self setupCellsWithNoClosestRenterCell:cell atIndexPath:indexPath];
}

return cell;

}

如您所见,第0部分将获得其自己的单元格标识符.如第1节所述.结果是,当要对一个单元进行出队时,它将检查indexPath当前位于哪个部分并获取正确的单元.

As you can see, section 0 will get its own cell identifier. As will section 1. The result is that when a cell is to be dequeued, it will check which section the indexPath is currently at and grab the correct cell.

嗯,这样令人沮丧的问题,但现在一切都说得通了:)

Ugh, such a frustrating problem but now it all makes sense :)

这篇关于iOS:CellForRowAtIndexPath单元格变得混乱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆