我有一个简单的预装SQLite DB和Core Data模型,其实体名为“Scales”,其中包含一个NSString“name”和一个名为“categories”的NSString字段(我决定不使用关系,因为这是一个简单的一对一,没有大量的数据)。
使用核心数据的当前设计如下:类别[a到z]的UITableViewController - >点击类别 - > DetailTableViewController显示属于该“类别”的所有“名称”[a到z]。
我能够使用标准的Apple提取方式和使用谓词进行排序来完成这些向下钻取的任务,但是它确实需要向堆栈添加另一个视图控制器。
我的目标是能够使用可扩展的UItableview,其中节名称是“类别”,单元格是“名称”;从而使得不必将详细视图推入堆栈/使应用程序更美观。
我试图将Tim Moose的TLIndexPathTools中的CollapseTableViewController与我的项目集成,但我仍然不清楚细节...。具体来说,在哪里链接我的managedObjectcontext和获取说明符,以便他的工具可以完成剩下的工作
答案 0 :(得分:1)
要与核心数据集成,您只需将TLCollapsibleTableViewController's
默认TLIndexPathController
替换为使用NSFetchRequest
初始化的- (void)viewDidLoad
{
[super viewDidLoad];
// replace default indexPathController with one configured with an NSFetchRequest
NSManagedObjectContext *context = ...;// Your managed object context
NSFetchRequest *fetch = ...; // Request that fetches Scales sorted by category
self.indexPathController = [[TLIndexPathController alloc] initWithFetchRequest:fetch managedObjectContext:context sectionNameKeyPath:@"categories" identifierKeyPath:nil cacheName:nil];
// perform initial fetch
NSError *error;
[self.indexPathController performFetch:error];
if (error) {
// handle error
}
}
:
TLIndexPathControllerDelegate
本答案的其余部分解释了核心数据集成的工作原理,并突出了TLCollapsibleTableViewController
的一个很酷的功能。
TLCollapsibleDataModels
使用TLCollapsibleDataModels
作为数据模型。 TLCollapsibleDataModel *dataModel = [[TLCollapsibleDataModel alloc] initWithBackingDataModel:backingDataModel expandedSectionNames:expandedSectionNames];
是通过提供包含所有可能行和一组扩展部分名称的支持数据模型构建的:
backingDataModel
结果数据模型仅包含要显示的行(尽管可通过TLCollapsibleTableViewController
属性访问完整数据集)。 TLIndexPathController
做的是在用户展开或折叠部分时自动更新数据模型。
如上所述启用Core Data集成时,TLCollapsibleDataModel
还将自动更新初始提取结果和任何提取结果更改的数据模型。但是这个数据模型是支持模型,需要转换为controller:willUpdateDataModel:withDataModel:
。为了实现这一点,我添加了- (TLIndexPathDataModel *)controller:(TLIndexPathController *)controller willUpdateDataModel:(TLIndexPathDataModel *)oldDataModel withDataModel:(TLIndexPathDataModel *)updatedDataModel
{
// If `updatedDataModel` is already a `TLCollapsibleDataModel`, we don't need to do anything.
if ([updatedDataModel isKindOfClass:[TLCollapsibleDataModel class]]) {
return nil;
}
// Otherwise, we assume `updatedDataModel` is the backing model - maybe it came from a
// Core Data fetch request or maybe it was provided by custom code - and we need to
// constructe the `TLCollapsibleDataModel`.
NSMutableSet *expandedSectionNames = nil;
// If `oldDataModel` is a `TLCollapsibleDataModel`, we need to preserve the
// expanded state of known sections.
if ([oldDataModel isKindOfClass:[TLCollapsibleDataModel class]]) {
expandedSectionNames = [NSMutableSet setWithSet:((TLCollapsibleDataModel *)oldDataModel).expandedSectionNames];
// Now filter out any section names that are no longer present in `updatedDataModel`
[expandedSectionNames intersectSet:[NSSet setWithArray:updatedDataModel.sectionNames]];
}
// Construct and return the `TLCollapsibleDataModel`
TLCollapsibleDataModel *dataModel = [[TLCollapsibleDataModel alloc] initWithBackingDataModel:updatedDataModel expandedSectionNames:expandedSectionNames];
return dataModel;
}
的以下实现,它允许在生成更新之前任意修改新数据模型:
updatedDataModel
因此,如果TLCollapsibleDataModel
不是TLCollapsibleDataModel
,则会假定它是支持模型并转换为oldDataModel
,从而保留在NSFetchRequest
中捕获的展开状态。这不仅适用于self.indexPathController.items = ...
生成的更新,而且如果您有任何理由,还可以在自定义代码self.indexPathController.dataModel = ...
或{{1}}中设置支持模型。