NSFetchedResultsController 不更新 UITableView 的部分索引
Posted
技术标签:
【中文标题】NSFetchedResultsController 不更新 UITableView 的部分索引【英文标题】:NSFetchedResultsController not updating UITableView's section indexes 【发布时间】:2010-01-03 20:55:02 【问题描述】:我正在使用 NSFetchedResultsController 填充 UITableViewController,结果创建填充部分标题和部分索引的部分。我正在使用以下方法来填充节索引:
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
return [fetchedResultsController_ sectionIndexTitles];
现在我遇到了一个问题。当我将新元素添加到与 NSFetchedResultsController 关联的 NSManagedObjectContext 时,新元素将被保存并适当地显示为 UITableView 中的单元格......除了一件事。如果新元素创建了一个新的 SECTION,新的部分索引不会显示在右侧边距中,除非我弹出 UINavigationController 的堆栈并重新加载 UITableViewController。
我已经符合NSFetchedResultsControllerDelegate的接口,手动调用
[self.tableView reloadSectionIndexTitles];
在这两个委托方法的末尾:
controller:didChangeSection...
controller:didChangeObject...
虽然我可以调试并跟踪方法的执行并查看调用的重新加载调用,但 UITableView 的节索引从不反映节的更改。
再次显示数据 - 新部分在 UITableView 中物理可见(或删除),但部分索引未更新。
我错过了什么吗?
【问题讨论】:
在另一篇文章中,“Tim”提到了以下内容:“在 3.0 SDK 中存在一个已知错误,如果您使用表数据源中的 NSFetchedResultsController。” ***.com/questions/994359/… 但不幸的是,看起来我正在构建“模拟器 - 3.1”。可能还没修好? 【参考方案1】:看起来这是我们都有的错误。请参阅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 行代码。所以,当苹果修复他们的 bug 时,你可以轻松将其移除。
【讨论】:
这确实有效。我暂时不使用部分索引,但感谢您的研究。 +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 根本不是我想要的,因为我必须处理各种动画问题。
希望对遇到同样问题的人有所帮助!
【讨论】:
我不记得了,但这只是让reloadSectionIndexTitles
工作的技巧,不管你在哪里调用它。请注意,这个答案有 3.5 年的历史,可以追溯到 ios 3,此后发生了很大变化。【参考方案3】:
要将已接受的答案与 Alex Reynolds 的答案与延迟相结合,只需调用 reloadData
,延迟对应于动画持续时间,即 0.4 或 0.3 秒。
在我的例子中,我将延迟的方法调用粘贴到控制器中:didChangeSection:atIndex:forChangeType:(它是一个核心数据应用程序)。
添加或删除部分时的结果是单元格的标准动画,然后是重新加载数据时更新的索引。
这很丑,让我畏缩,但我对结果没意见。我还向 Apple 提交了一个错误,#8589547。
【讨论】:
【参考方案4】:尝试将它放在-controllerDidChangeContent:
的末尾,[self.tableView endUpdates]
之后的某个位置。
【讨论】:
感谢您的建议。不幸的是,这对我不起作用。我认为这可能是一个错误,但不确定如何检查或确认。请参阅我添加到原始问题的评论。感谢您的建议。【参考方案5】:我做的另一件事(对我有用,不能保证它对你有用)是在很短的延迟后执行选择器,例如:
[self performSelector:(@selector(refreshSectionIndex)) withObject:nil afterDelay:0.2];
// ...
- (void) refreshSectionIndex
[self.tableView reloadSectionIndexTitles];
Core Data 和NSFetchedResultsController
看起来特别糟糕,其中委托表视图更新与获取的数据不同步,导致应用程序崩溃。我真的希望 Apple 正在采取措施修复 4.0 SDK 中这些框架中的错误。真是令人沮丧。
【讨论】:
我在保存一个新元素后尝试了这个。新元素出现。该元素的新部分出现了 - 但不幸的是,新的部分索引标题丢失了。再次感谢您的建议。 如果你想这样做,你不必在你的视图控制器上创建另一个方法,你可以直接在 tableView 上调用它:[tv performSelector:@selector(reloadSectionIndexTitles) withObject:nil afterDelay:0.2];
以上是关于NSFetchedResultsController 不更新 UITableView 的部分索引的主要内容,如果未能解决你的问题,请参考以下文章