NSFetchedResultsController,分组 UITableView、HeaderInSection 和 NSSortDescriptor

Posted

技术标签:

【中文标题】NSFetchedResultsController,分组 UITableView、HeaderInSection 和 NSSortDescriptor【英文标题】:NSFetchedResultsController, grouped UITableView, HeaderInSection and NSSortDescriptor 【发布时间】:2012-04-25 18:24:48 【问题描述】:

我有一个带有 NSSortDesctriptors 的 NSFetchRequest 附加到 NSFetchedResultController 为处于分组模式并显示部分标题的 UITableView 提供数据(参见表示例)。

我在正确排序以显示部分时遇到了一些问题。

数据:

+---+----------+------------+----------+
|id | subTitle | groupTitle | distance |
+---+----------+------------+----------+
|1  | A        | T1         | 1.1      |
+---+----------+------------+----------+
|2  | B        | T1         | 1.2      |
+---+----------+------------+----------+
|3  | C        | T1         | 3.0      |
+---+----------+------------+----------+
|4  | D        | T2         | 1.3      |
+---+----------+------------+----------+
|5  | E        | T2         | 1.4      |
+---+----------+------------+----------+
|6  | F        | T3         | 1.5      |
+---+----------+------------+----------+

我有什么:

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"groupTitle" ascending:YES];

--T1
------A
------B
------C
--T2
------D
------E
--T3
------F

我想要什么:(按距离排序,但按 groupTitle 对同一组中的以下每个项目进行分组)

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"distance" ascending:YES];

--T1
------A
------B
--T2
------D
------E
--T3
------F
--T1
------C

我怎样才能实现这种行为?可能使用 viewForHeaderInSection 方法? 如果要分组的部分不在[self.fetchedResultsController sections] 的第一个层次结构中怎么办?

//custom header
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

    id<NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
    SomeObject *cellEntity = (SomeObject *)[[sectionInfo objects] objectAtIndex:0];
    //cellEntity.groupTitle is the title 
    return aView;

【问题讨论】:

您可以以编程方式添加一个核心数据实体属性,该属性代表您实际需要的排序,但这不能成为更大数据集的解决方案。 【参考方案1】:

您是否尝试过以这种方式设置您的 NSFetchedResultsController?这应该首先按组标题排序,然后按距离排序。然后它应该按组打破它。

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"MyEntity"];
NSSortDescriptor *groupTitleSort = [NSSortDescriptor sortDescriptorWithKey:@"groupTitle" ascending:YES];
NSSortDescriptor *distanceSort = [NSSortDescriptor sortDescriptorWithKey:distance ascending:YES];
NSArray *sortArray = [NSArray arrayWithObjects:groupTitleSort, distanceSort, nil];
request.sortDescriptor = sortArray;
NSFetchedResultController *fetchedResults = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:myManagedObjectContext sectionNameKeyPath:@"groupTitle" cacheName:@"MyCache"];

...Finish performing fetch...

【讨论】:

这不是我需要的,它应该首先按距离排序,但按 groupTitle 分组: NSArray *sortArray = [NSArray arrayWithObjects:distanceSort, groupTitleSort, nil];这是我需要的,但这会破坏分组,因为 fetchedResultController 中的第一部分是距离。 好吧,我误解了你的意思。我认为 NSFetchRequest 不会满足您的需求。只需按距离对对象进行排序,然后按 groupTitle。然后使用数组作为数据源而不是 NSFetchRequest。通过预先计算部分(groupTitle 中的更改)和更改之间的行数来扮演 NSFetchRequest 的一部分。使用它在 DataSource 委托中返回。

以上是关于NSFetchedResultsController,分组 UITableView、HeaderInSection 和 NSSortDescriptor的主要内容,如果未能解决你的问题,请参考以下文章

在 Core Data 应用程序中调用 performFetch 后,是不是需要手动更新表视图?