NSFetchedResultsChangeMove在自定义UITableViewCell中显示不正确的标签

时间:2012-03-31 02:30:50

标签: uitableview uilabel nsfetchedresultscontroller uistoryboard

我很确定有一种更简单的方法可以做到这一点,我在所有阅读中都遗漏了...但这让我感到疯狂。我很累 - 如果这很冗长,请道歉。

我在我的应用程序中使用NSFetchedResultsController - 非常标准的问题 - 它的工作原理。两个部分,正确排序等。当用户点击第一部分中的单元格(创建两个部分的属性的BOOL值相反)时 - 它移动到第二部分(BOOL值再次翻转) - 反之亦然。 ..gain,作品着名。

这是我的实现有点时髦的地方。最终我想支持iAds - 根据HIG,这些应该放在屏幕的底部...我发现这样做的最简单的方法是将UITableView放在UIView中,以避免一些逻辑上的原因让我现在逃脱 - 但这就是我所拥有的 - 使用UITableView进行UIView。

我正在使用故事板和原型单元 - 两个是具体的。一个用于添加内容,并充当两个部分之间的分隔符。另一个是要显示的默认单元格。当我为这个单元格注册IBOutlets时 - 它抛出异常(这是一个问题,但我能够解决它)。所以,相反,我一直在做的是使用cell.contentView.subviews来获取我需要弄乱的元素:

    NSArray *cellSubViews = cell.contentView.subviews;
if ([cellSubViews count] == 3) {
    // editing accessory view
    cell.editingAccessoryType = UITableViewCellAccessoryDisclosureIndicator;

    // default background image view
    cell.backgroundView = self.defaultClockCellBackgroundImageView;

    // clock name label
    UILabel *clockNameLabel = [cellSubViews objectAtIndex:2];
    clockNameLabel.text = clock.name;
    clockNameLabel.textColor = (indexPath.section == 0 && ![clock.isAddClockCell boolValue])
    ? [UIColor whiteColor]
    : [UIColor lightTextColor];

    // view child button
    UIButton *viewChildButton = [cellSubViews objectAtIndex:0];
    UIImage *viewChildClocksButtonBackgroundImage;
    if (self.clockForFetch != nil) {
        //NSLog(@"child clocks list - N/A");
        viewChildClocksButtonBackgroundImage = [UIImage imageNamed:@"childcell_blank"];
        viewChildButton.enabled = NO;

    } else if ([clock.childClocks count] < 2) {
        //NSLog(@"add child button");
        viewChildClocksButtonBackgroundImage = [UIImage imageNamed:@"parentcell_addchild"];

    } else if (![clock.isRunning boolValue] 
               || [self totalChildClocksRunning:clock] < 1) {
        //NSLog(@"view child button");
        // children clocks cannot be running while parent is stopped; 
        // therefore, no need to actually check
        // this solves the "wait for cell animation to end" issue 
        // without the need for tableview reload data
        viewChildClocksButtonBackgroundImage = [UIImage imageNamed:@"parentcell_viewchild"];

    } else {
        //NSLog(@"view child running button");
        viewChildClocksButtonBackgroundImage = [UIImage imageNamed:@"parentcell_viewchild_running"];

    }
    [viewChildButton setImage:viewChildClocksButtonBackgroundImage forState:UIControlStateNormal];
    viewChildButton.hidden = NO;

    // view time entries list for clock
    UIButton *detailDisclosureButton = [cellSubViews objectAtIndex:1];
    UIImage *detailDisclosureButtonBackgroundImage = (self.clockForFetch == nil) 
    ? [UIImage imageNamed:@"parentcell_detaildisclosure"] 
    : [UIImage imageNamed:@"childcell_detaildisclosure"];
    [detailDisclosureButton setImage:detailDisclosureButtonBackgroundImage 
                            forState:UIControlStateNormal];
    detailDisclosureButton.hidden = NO;

    if (self.editing) {
        viewChildButton.hidden = YES;
        detailDisclosureButton.hidden = YES;
    }
}

请注意:在此方法之前,我使用了一个单独的NIB和IBOutlets,可以复制问题 - 只是不一致。

下面是三个单元格在敲击时移动的表格(Alpha,Beta和Gamma)......啊,没有图像给新抱歉 - 希望他们能告诉我在上传图像之前 - 输入ASCII艺术:

---------------
|    alpha    |
---------------
|    beta     |
---------------
|    gamma    |
---------------
| *delimiter* |
---------------

点击Alpha和Beta细胞后的表格如下:

---------------
|    gamma    |
---------------
| *delimiter* |
---------------
|    beta     |
---------------
|    beta     |
---------------

但是,如果我点击标记为“Beta”的第一个单元格中的自定义详细信息公开按钮(应该读取Alpha),我会将正确的对象传递给详细信息视图:

--------------------------------------------
| < back    detail view for alpha     edit |
--------------------------------------------

因此,正在更新获取的结果控制器 - 它在与表视图进行通信时似乎并不一致地配置事物。在上面的配置单元格方法中,我检查了控制器中找到的对象的名称 - 它们也是正确的;即,第一个β单元格(索引路径为1,0的行的单元格)是Alpha - 而不是Beta - 即使表格视图显示Beta。

我一直看到提到需要setNeedsDisplay和/或setNeedsLayout的自定义单元格,但我不认为我非常理解那个 - 虽然我已经尝试将其放在我能想到的代码中的几乎所有位置。 “NSFetchedResultsChangeMove”是用户点击一个单元格时调用的内容 - 我尝试了很多我在网上看到的变化(包括这里)来修复我认为类似的故障 - 无济于事。

我确信这个结构会随着时间的推移而成熟(因为这是第一次)但是,正如我所说,我遇到了完全不同的构造(故事板当时不存在)的相同问题 - 并且可以仍然重复这个问题。

非常感谢任何帮助。而且,如果这里有一个完全相同问题的答案,我为重复道歉。

1 个答案:

答案 0 :(得分:0)

所以,这就是我为解决这个问题所做的工作,看来我可以想到两个可能的问题贡献者;希望如果他们发现自己处于同样的境地,这会有所帮助。

  1. 我有两个不同的原型单元格:默认单元格和分隔符单元格。因此,直接在索引路径上调用configure单元可能会导致意外结果。因此,在我可能调用configureCell atIndexPath的任何地方,我只是调用了cellForRowAtIndexPath。例如,在我提取的结果控制器更新表方法中,我改变了所有内容来调用cellForRowAtIndexPath(特别是更改更新的情况 - 通常在索引路径调用行的配置单元格:

    case NSFetchedResultsChangeUpdate:
        //NSLog(@"NSFetchedResultsChangeUpdate");
        [self.TJTableView cellForRowAtIndexPath:indexPath];
        break;
    
  2. 使用子视图遍历单元格内容视图似乎并不能保持自己,并且它不是一种非常优雅的做事方式;所以,我根据这里的教学文章 - http://bit.ly/oI2GGW将自定义单元子类化为UITableViewCell - 这样我就可以连接IBOutlets并直接在索引路径的配置行中引用标签和按钮。