NSFetchedResultsController - 父母和祖父母作为部分标题

Posted

技术标签:

【中文标题】NSFetchedResultsController - 父母和祖父母作为部分标题【英文标题】:NSFetchedResultsController - parent and grandparent as section title 【发布时间】:2013-11-20 14:18:25 【问题描述】:

我正在尝试使用 NSFetchedResultsController 创建分段的 TableView。我的数据模型如下所示:

城市>区>街道

我的 TableView 应该是这样的:

,------------,
| City 1     |    --- Section 0
`------------´

,------------,
| District 1 |    --- Section 1
`------------´
| Street 1   |    --- Row 0
`------------´
| Street 2   |    --- Row 1
`------------´

,------------,
| District 2 |    --- Section 2
`------------´
| Street A   |    --- Row 0
`------------´
| Street B   |    --- Row 1
`------------´

,------------,
| City 2     |   --- Section 3
`------------´

问题是,如果我在 FetchedResultsController 上定义 sectionNameKeyPath,我只能得到地区名称或城市名称,但不能同时得到两者。 这甚至可能吗?

到目前为止,这是我的FetchedResultsController

- (NSFetchedResultsController *)fetchedResultsController 

    if (_fetchedResults != nil) 
        return _fetchedResults;
    

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Street" inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"toDistrict.toCity.toUser.userId = %@",currentUser.userId];

    NSSortDescriptor *sortCities = [[NSSortDescriptor alloc] initWithKey:@"toDistrict.toCity.name" ascending:YES];
    NSSortDescriptor *sortDistricts = [[NSSortDescriptor alloc] initWithKey:@"toDistrict.name" ascending:YES];
    NSSortDescriptor *sortStreets = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortCities, sortDistricts, sortStreets, nil]];

    [fetchRequest setFetchBatchSize:20];
    [fetchRequest setPredicate:predicate];
    NSFetchedResultsController *theFetchedResultsController =
    [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"toDistrict.toCity.name" cacheName:@"Root"];
    self.fetchedResults = theFetchedResultsController;
    fetchedResults.delegate = self;

    return _fetchedResults;


为了实现 TableView 的上述外观,我需要进行哪些更改?还是我完全错了,需要不同的结构?

任何提示和帮助将不胜感激。

【问题讨论】:

那个表格视图的层次结构很难理解。上图中的第 0 节是对第 1 节和第 2 节进行分组吗?这对于 UITableView 来说是不可能的。你只能有2个级别;节标题和节标题的行。你需要添加一些巫术来实现你想要的,但我不会推荐它。 【参考方案1】:

我会执行以下操作:获取Street 实体并在创建获取的结果控制器时使用与District 实体的关系作为sectionNameKeyPath。您需要有一个明确的方式来对区域进行排序,并且一个区域在查询时应该知道它在这个层次结构中的位置。

从您的图表中可以清楚地看出,城市和地区标题之间没有空格。因此,您可以只返回一个结合了两者的更大的特殊标头。每个区都必须知道它是全市第一,并通知表视图datasource 方法添加上面的附加信息。

请注意,您必须在 viewForHeaderInSection:heightForHeaderInSection: 中都考虑到这一点。

【讨论】:

我真的很喜欢这个想法并试图实现它。不幸的是,我只是按地区和街道名称排序,而不是按城市名称排序。这弄乱了我的 tableview 结构。拥有上述结构对我来说很重要。 您还可以获取没有部分标题的地区,按国家/地区排序,并在您的数据源中使用district.streets作为部分下的行。【参考方案2】:

我认为 NSFetchedResultsController 无法实现您想要实现的目标,因为您指出 sectionNameKeyPath 确实限制了您。同时,作为用户,我很确定我希望有一个城市的第一个列表,一旦选择推送另一个包含该地区的视图控制器,然后再次选择显示街道。它将允许您的应用包含更多数据,而不会将您的用户丢失到一个无休止的大列表中。

【讨论】:

你是对的,但这是给我的设计,我不允许使用另一个。所以我需要想办法处理它。

以上是关于NSFetchedResultsController - 父母和祖父母作为部分标题的主要内容,如果未能解决你的问题,请参考以下文章

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