ind*_*gie 26 iphone cocoa-touch core-data uitableview nsfetchedresultscontroller
我想做的很简单.在我的UITableViewController中,我想从多个NSFetchedResultControllers加载数据(我的数据模型中有多个实体),并将每个数据放入表视图中的不同部分.因此,例如,来自第一个NSFetchedResultController的所有获取的项目将在UITableView中的第0部分中,从另一个中获取的项目将进入第1部分,等等.
核心数据模板项目未演示如何执行此操作.所有内容(主要是索引路径)都是在不考虑部分的情况下编码的(默认模板中没有部分),所有内容都来自单个NSFetchedResultController.是否有任何示例项目或文档可以证明这样做?
谢谢
Gia*_*iao 25
假设你的标题中有以下内容(下面的代码会略显草率,我的道歉):
NSFetchedResultsController *fetchedResultsController1; // first section data
NSFetchedResultsController *fetchedResultsController2; // second section data
Run Code Online (Sandbox Code Playgroud)
让表知道你想要有两个部分:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2; // you wanted 2 sections
}
Run Code Online (Sandbox Code Playgroud)
给它部分标题:
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return [NSArray arrayWithObjects:@"First section title", @"Second section title", nil];
}
Run Code Online (Sandbox Code Playgroud)
让表知道每个部分有多少行:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == 0) {
return [[fetchedResultsController1 fetchedObjects] count];
} else if (section == 1) {
return [[fetchedResultsController2 fetchedObjects] count];
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
构建单元格:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
... // table cell dequeue or creation, boilerplate stuff
// customize the cell
if (indexPath.section == 0) {
// get the managed object from fetchedResultsController1
// customize the cell based on the data
} else if (indexPath.section == 1) {
// get the managed object from fetchedResultsController2
// customize the cell based on the data
}
return cell;
}
Run Code Online (Sandbox Code Playgroud)
多个 fetch 控制器(可能还有多个实体)是错误的方法。正确的解决方案是使用sectionNameKeyPath
param toNSFetchedResultController
将结果分组为多个部分。如果您以不同的方式考虑您的实体,也许它们实际上是同一个实体,而您可以使用一个属性itemType
,然后您可以对其进行分区(并且您也必须对其进行排序)。例如说我有实体 Hops 和 Grains 然后我可以将它们更改为 Ingredient 并有一个 int_16 属性ingredientType
,然后我在代码中有一个枚举来存储值hopType = 0
,grainType = 1
。毕竟成分只是一个名称和一个重量,这两者都是共享的。
然而,如果您的实体确实具有一组不同的属性,那么正确的解决方案是创建一个父抽象实体,该实体具有您可以用来分割的属性,例如sortOrder
,sectionID
或type
。然后,当您创建一个提取控制器并提取抽象父实体时,您实际上会获得包含所有子实体的结果。例如,在 Notes 应用程序中,他们有一个抽象的父实体NoteContainer
,其中包含子实体Account
和Folder
. 这使单个提取控制器能够在该部分的第一个单元格中显示帐户,然后在以下单元格中显示所有文件夹。例如,所有 iCloud 备忘录(实际上是帐户),然后是备忘录(是默认文件夹),然后是所有自定义文件夹,然后是垃圾文件夹。他们使用一个sortOrder
属性和默认文件夹是1
,自定义文件夹都是2
,垃圾箱是3
。然后通过将其添加为排序描述符,他们可以按照他们想要的顺序显示单元格。它与您的要求有点不同,因为它们将 2 个实体混合到不同的部分,但您仍然可以仅使用不同的排序属性来使用它。
这个故事的寓意是不要与框架作斗争,拥抱它:-)
小智 5
使用两个NSFetchedResultsControllers扩展Giao的解决方案 - 我们必须记住我们的NSFetchedResultsController不知道我们的两个部分,并且返回的NSIndexPathes将始终用于第一部分.
所以当我们在单元格配置中获取对象时:
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (!cell) {
[tableView registerNib:[UINib nibWithNibName:@"cell" bundle:nil] forCellReuseIdentifier:@"cell"];
cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
-(void)configureCell:(UITableViewCell*)cell atIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
NSManagedObject *object = [self.fetchedResults1 objectAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:0]];
//use object to configure cell
} else {
NSManagedObject *object = [self.fetchedResults2 objectAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:0]];
//use object to configure cell
}
}
Run Code Online (Sandbox Code Playgroud)
在NSFetchedResultsController注意到一些更改时更新单元格:
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
NSIndexPath *customIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:(controller == self.fetchedResultsController1)?0:1];
NSIndexPath *customNewIndexPath = [NSIndexPath indexPathForRow:newIndexPath.row inSection:(controller == self.fetchedResultsController2)?0:1];
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:customNewIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:customIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:customIndexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:customNewIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
9653 次 |
最近记录: |