NSFetchedResultsController不更新UITableView的节索引

时间:2010-01-03 20:55:03

标签: iphone uitableview core-data nsfetchedresultscontroller

我正在使用NSFetchedResultsController填充UITableViewController,其中结果创建了用于填充节标题和节索引的节。我使用以下方法填充节索引:

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
    return [fetchedResultsController_ sectionIndexTitles];
}

现在我遇到了一个问题。当我向与NSFetchedResultsController关联的NSManagedObjectContext添加新元素时,新元素将被保存并在UITableView中适当地显示为单元格...除了一件事。如果new元素创建了一个新的SECTION,那么除非我弹出UINavigationController的堆栈并重新加载UITableViewController,否则新的section索引不会显示在右边距中。

我已经符合NSFetchedResultsControllerDelegate的界面并手动调用

[self.tableView reloadSectionIndexTitles];

在这两个委托方法的末尾:

controller:didChangeSection... 
controller:didChangeObject...

虽然我可以调试并跟踪执行到方法中并查看调用的重载调用,但UITableView的节索引从不反映节的更改。

同样,数据显示 - UITableView中的新部分在物理上可见(或删除)但部分索引未更新。

我错过了什么吗?

5 个答案:

答案 0 :(得分:7)

看起来这是我们所有的错误。请参阅http://iphonedevelopment.blogspot.com/2009/11/i-know-youre-tired-of-hearing-about.html,看起来像是一个相当令人讨厌的太多行代码解决方案。我跟着这个:

- (void)viewWillAppear:(BOOL)animated; {
  // This is a dumb hack required by this bug: http://iphonedevelopment.blogspot.com/2009/11/i-know-youre-tired-of-hearing-about.html
  [self.tableView reloadData];
}

它可能效率低下但除非你有大量的数据,否则它可能不会造成任何伤害。它只有一行代码。因此,当苹果修复他们的错误时,你可以轻松地将其删除。

答案 1 :(得分:1)

问题已经2个月了,但我今天遇到了同样的问题。似乎-reloadSectionIndexTitles根本不起作用,所以我尝试了几个潜在的黑客,以下哪些对我有用:

@implementation UITableView (JKAdditions)

- (UIView *)indexView {
    Class indexClass = NSClassFromString(@"UITableViewIndex");
    for(UIView *subview in self.subviews){
        if([subview isKindOfClass:indexClass]) return subview;
    }
    return nil;
}

- (void)reloadSectionIndexTitles {
    UIView *indexView = [self indexView];
    [indexView performSelector:@selector(setTitles:) withObject:[self.dataSource sectionIndexTitlesForTableView:self]];
    [indexView setNeedsDisplay];
}

@end

我真的不知道Apple是否因为这种黑客而拒绝你的应用程序,但它似乎是我的唯一选择。重新加载整个tableView根本不是我想要的,因为我必须处理各种动画问题。

我希望这可以帮助任何有同样问题的人!

答案 2 :(得分:1)

要将接受的答案与Alex Reynolds的答案与延迟相结合,只需按照与动画持续时间相对应的延迟调用reloadData,即0.4或0.3秒。

在我的情况下,我将延迟的方法调用粘贴到控制器:didChangeSection:atIndex:forChangeType :(它是一个核心数据应用程序)。

添加或删除部分时,结果是单元格的标准动画,然后在重新加载数据时更新索引。

这很丑,让我感到畏缩,但我对结果没问题。我还向Apple提交了一个错误,#8589547。

答案 3 :(得分:0)

尝试将其放在-controllerDidChangeContent:之后[self.tableView endUpdates]之后的某个地方。

答案 4 :(得分:0)

我做的另一件事(对我有用,不能保证它对您有用)是在很短的延迟后执行一个选择器,例如:

[self performSelector:(@selector(refreshSectionIndex)) withObject:nil afterDelay:0.2];

// ...

- (void) refreshSectionIndex {
    [self.tableView reloadSectionIndexTitles];
}    

核心数据和NSFetchedResultsController特别容易出错,其中委托表视图更新与获取的数据不同步,导致应用程序崩溃。我真的希望Apple正在采取措施来修复4.0 SDK中这些框架中的错误。这非常令人沮丧。