2

I'm using MagicalRecord to create an NSFetchedResultsController for a table.

I've got NSManagedObjects that contain groups of people, here are two examples:

ContactGroup *everyoneContactGroup = [ContactGroup findFirstByAttribute:@"groupId" withValue:@"<GROUPID>"];
if (!everyoneContactGroup) {
    everyoneContactGroup = [ContactGroup createEntity];
    [everyoneContactGroup setGroupId:@"<GROUPID>"];
    [everyoneContactGroup setGroupName:@"Everyone"];
    [everyoneContactGroup setGroupSortOrder:@1]; // sort order within section
    [everyoneContactGroup setGroupType:@1];
    [everyoneContactGroup setGroupTypeName:@"Smart Groups"];
    [everyoneContactGroup setGroupTypeSortOrder:@0]; // sort order for groups
}

ContactGroup *closeFriendsContactGroup = [ContactGroup findFirstByAttribute:@"groupId" withValue:@"<GROUPIDCLOSEFRIENDS>"];
if (!closeFriendsContactGroup) {
    closeFriendsContactGroup = [ContactGroup createEntity];
    [closeFriendsContactGroup setGroupId:@"<GROUPIDCLOSEFRIENDS>"];
    [closeFriendsContactGroup setGroupName:@"Close Friends"];
    [closeFriendsContactGroup setGroupSortOrder:@2];
    [closeFriendsContactGroup setGroupType:@2];
    [closeFriendsContactGroup setGroupTypeName:@"Custom Groups"];
    [closeFriendsContactGroup setGroupTypeSortOrder:@10];
}

ContactGroup *familyContactGroup = [ContactGroup findFirstByAttribute:@"groupId" withValue:@"<GROUPIDFAMILY>"];
if (!familyContactGroup) {
    familyContactGroup = [ContactGroup createEntity];
    [familyContactGroup setGroupId:@"<GROUPIDFAMILY>"];
    [familyContactGroup setGroupName:@"Family"];
    [familyContactGroup setGroupSortOrder:@1];
    [familyContactGroup setGroupType:@2];
    [familyContactGroup setGroupTypeName:@"Custom Groups"];
    [familyContactGroup setGroupTypeSortOrder:@10];
}

The above should show up as follows:

enter image description here

As you can see, the contact group "Everyone" should be grouped into a section of its own and should appear as the first group in the order of the groups.

The second and third contact group above should be grouped into a section together and this section should appear below the other section with one group in it. Inside this group ("Custom Groups") each contact group should be sorted by their groupSortOrder.

Here's my NSFetchedResultsController code:

- (NSFetchedResultsController *)fetchedResultsController {
    if (!fetchedResultsController) {
        fetchedResultsController = [ContactGroup fetchAllSortedBy:@"groupTypeSortOrder,groupSortOrder"
                                                           ascending:YES
                                                       withPredicate:nil
                                                             groupBy:@"groupTypeName"
                                                            delegate:self];
    }
    return fetchedResultsController;
}

I have tried various combinations but cannot get the sort order both for each table view section (group of contact groups) and within each table view section. I know you can add comma-delimited sort attributes, but I just cannot get the combination right. Anyone know if it's possible to achieve what I want with MagicalRecord or do I have to roll some non-MR code .

Thanks in advance for any input and help!

UPDATE:

Here's the SQL being generated by Core Data:

CoreData: sql: 
SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZGROUPID,  t0.ZGROUPNAME, t0.ZGROUPSORTORDER, 
t0.ZGROUPTYPE, t0.ZGROUPTYPENAME, t0.ZGROUPTYPESORTORDER 
FROM ZTCONTACTGROUP t0 
ORDER BY t0.ZGROUPTYPESORTORDER, t0.ZGROUPSORTORDER

UPDATE:

So I have tried with grouping by groupTypeSortOrder and it works correctly now. However, not I cannot get the section name to appear correctly as it will appear with the numbers for groupTypeSortOrder instead. Any ideas?

- (NSFetchedResultsController *)fetchedResultsController {
    if (!fetchedResultsController) {
        fetchedResultsController = [ContactGroup fetchAllSortedBy:@"groupTypeSortOrder,groupSortOrder"
                                                           ascending:YES
                                                       withPredicate:nil
                                                             groupBy:@"groupTypeSortOrder"
                                                            delegate:self];
    }
    return fetchedResultsController;
}
4

1 回答 1

3

我还没有使用过 MagicalRecord,但我假设参数groupBy:对应于.sectionNameKeyPath:NSFetchedResultsController

如果键被指定为sectionNameKeyPath,则获取请求必须具有使用相同键(或生成相同相对排序的键)的第一个排序描述符。

因此,使用groupTypeSortOrder作为第一个排序键并作为groupBy:参数是正确的方法。

现在,要将组名而不是数字显示为节标题,您可以修改该titleForHeaderInSection方法,该方法通常如下所示:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.controller sections] objectAtIndex:section];
    return [sectionInfo name];
}

但是[sectionInfo name]groupTypeSortOrder的值,因为它已被指定为sectionNameKeyPath(或groupBy)。如果您像这样修改方法:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.controller sections] objectAtIndex:section];
    return [[[sectionInfo objects] objectAtIndex:0] groupName];
}

groupName属性改为显示为节标题。

于 2013-01-22T18:51:07.013 回答