草庐IT

iOS:CellForRowAtIndexPath 单元格混淆了

coder 2023-09-25 原文

首先要说我已经看到了这些问题:

iOS: UITableView mixes up data when scrolling too fast

(custom) UITableViewCell's mixing up after scrolling

Items mixed up after scrolling in UITableView

第一个和最后一个似乎与我的问题非常相关,但是我相当确定每个部分都有逻辑来确定单元格中应该出现什么(数据),但它们仍然会混淆。

相关代码如下:

- (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 子句……事实就是如此。

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 个部分。

问题是第 0 部分(第一部分)应该只有占位符字符串。第 1 部分应该包含我的自定义 subview (在单元格中,它确实如此)。

第 0 部分最初只有占位符字符串,但是一旦我向下滚动(并且该部分不再可见)并向上滚动(快速),它有时会有一个来自第 1 部分的看似随机的单元格......这是什么哎呀?如何?我不愿意责怪细胞重复使用,但在这一点上,除了一些非常愚蠢的事情之外,我不知道它是什么。

这里令人不安的部分是第 0 节中的单元格(那里只有 1 行)没有 subview 。但是当我快速上下滚动时,它得到一个(显然来自第 1 节)然后我得到“WHAT THE HECK”日志消息......

应该值得一提的是,使用 for 循环(带有到底是什么消息的循环)确实解决了问题(因为它删除了不需要的 subview ),但必须有更好的方法。现在感觉不对。

有什么想法吗?

(请随意将此标记为重复,但我相当确定这里还有其他事情)。

谢谢。

最佳答案

所以在经历了一些挫折和仔分割析之后,我发现了细胞混淆的原因。

我关于单元重用(特别是标识符)的假设是问题所在。

以前我是这样做的:

static NSString *CellIdentifier = @"Cell";

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

这很好,但是有一个关键问题。所有单元格在技术上都是相同的......在它们全部分配(不是零)之后,系统无法确定要重用哪个单元格,无论它是哪个部分。

这意味着任何单元格都可以从队列中获取,无论它有什么,并卡在任何地方(尽管我检查以确保第 1 部分的内容进入第 1 部分,第 0 部分的内容(假承租人)保留在那里)。

解决方法:

- (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 当前位于哪个部分并获取正确的单元格。

呃,这是一个令人沮丧的问题,但现在一切都有意义了:)

关于iOS:CellForRowAtIndexPath 单元格混淆了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16425122/

有关iOS:CellForRowAtIndexPath 单元格混淆了的更多相关文章

  1. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  2. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  3. ruby-on-rails - Prawn - 表格单元格内的链接 - 2

    我正在尝试用Prawn生成PDF。在我的PDF模板中,我有带单元格的表格。在其中一个单元格中,我有一个电子邮件地址:cell_email=pdf.make_cell(:content=>booking.user_email,:border_width=>0)我想让电子邮件链接到“mailto”链接。我知道我可以这样链接:pdf.formatted_text([{:text=>booking.user_email,:link=>"mailto:#{booking.user_email}"}])但是将这两行组合起来(将格式化文本作为内容)不起作用:cell_email=pdf.make_c

  4. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  5. ruby - 单元测试文件 I/O 方法 - 2

    我对单元测试还是比较陌生。我用Ruby编写了一个类,它接受一个文件,在该文件中搜索给定的Regex模式,替换它,然后将更改保存回文件。我希望能够为此方法编写单元测试,但我不知道我将如何去做。有人能告诉我我们如何对处理文件i/o的方法进行单元测试吗? 最佳答案 看看这个HowdoIunit-testsavingfiletothedisk?基本上这个想法是一样的,文件系统是你的类的依赖。所以引入一个可以在你的单元测试中模拟的角色/接口(interface)(这样你在单元测试时就没有依赖性);角色中的方法应该是您从文件系统中需要的所有东西

  6. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  7. ruby - 尝试运行 minitest 单元测试时出错 - 2

    尝试使用rubytest/test_foo.rb运行minitest单元测试时出现以下错误:Warning:youshouldrequire'minitest/autorun'instead.Warning:oradd'gem"minitest"'before'require"minitest/autorun"'From:/home/emile/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/minitest/autorun.rb:15:```test_foo.rb看起来像这样:require'minitest/autorun'classTestFoo

  8. ruby 单元测试 : run some code after each failed test - 2

    在Test::Unit中的ruby​​单元测试断言失败后,在执行teardown之前,是否有一些简洁优雅的方法来立即执行我的代码?我正在做一些自动化的GUI测试,并希望在出现问题后立即截图。 最佳答案 如果您使用的是1.9,请不要使用Test::Unit::TestCase作为您的基类。对其进行子类化并覆盖#run_test以进行救援,截取屏幕截图并重新提出:classMyAbstractTestCase或者,我认为这实际上是最简洁的方法,您可以使用before_teardownHook:classMyTestCase这不适用于1.

  9. ruby-on-rails - Ruby on Rails 单表继承(STI)和单元测试问题(使用 PostgreSQL) - 2

    我正在使用带有单个“帐户”表的STI模型来保存用户和技术人员的信息(即用户...8)错误:test_the_truth(用户测试):ActiveRecord::StatementInvalid:PGError:ERROR:关系“技术人员”不存在:从“技术人员”中删除...从本质上讲,标准框架不承认Technicians和Users表(或PostgreSQL称它们为“关系”)不存在,事实上,应该别名为Accounts。有什么想法吗?我对RoR比较陌生,不知道如何解决这个问题而又不完全删除STI。 最佳答案 原来问题是由于存在:./te

  10. ruby - 关于 Ruby 中 Dir[] 和 File.join() 的混淆 - 2

    我在Ruby中遇到了一个关于Dir[]和File.join()的简单程序,blobs_dir='/path/to/dir'Dir[File.join(blobs_dir,"**","*")].eachdo|file|FileUtils.rm_rf(file)ifFile.symlink?(file)我有两个困惑:首先,File.join(@blobs_dir,"**","*")中的第二个和第三个参数是什么意思?其次,Dir[]在Ruby中有什么用?我只知道它等价于Dir.glob(),但是,我对Dir.glob()确实不是很清楚。 最佳答案

随机推荐