使用NSFetchedResultsController的自定义部分?

时间:2009-09-05 21:53:42

标签: iphone cocoa-touch uitableview core-data

我正在制作一个带有结果的分段表,但我很难找到定制的部分。

通常,只有一个属性可以排序,并使用sectionNameKeyPath:生成这些节。但我的排序属性是动态计算的,我似乎无法让fetchedResultsController正确使用它...

更新:使用下面的jbrennan建议,我非常接近预期的功能。我添加了一个类别NSDate,返回“天前”号码;把它放在这里给我基于这些数字的部分:

NSFetchedResultsController *aFetchedResultsController =
    [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
    managedObjectContext:managedObjectContext
    sectionNameKeyPath:@"myDateAttribute.daysAgo"
    cacheName:@"Root"];

这就是我被困住的地方:我不需要按“天前”排序,我需要根据实体中其他属性的某些计算对它们进行排序。所以我不能只调用那个自定义的Category方法,我需要用参数调用一个方法,如下所示:

[myDateAttribute sortingRoutine:thisObject.value]

或类似的东西。我希望这有一定程度的意义。如果你能提供帮助,非常感谢:)

3 个答案:

答案 0 :(得分:16)

我在(即将推出)iPhone应用程序中做了类似的事情。我的部分被这样的日期划分:昨天,今天,明天,未来......

无论如何,我的诀窍是为NSDate添加一个Category来确定我所获取的对象属于哪个部分。

我的托管对象有一个名为dueDate的属性,它是一个NSDate。配置获取的结果控制器时,我使用@"dueDate.relativeDate"作为部分键路径。

在类别中,-relativeDate被声明为返回NSStringreadonly属性(其中任何一个都可能就足够了,我没有尝试,但两者都没有,但是同时使用方法和属性声明也没有什么坏处。然后我只是简单地实现了这个方法。

答案 1 :(得分:7)

您可以尝试以下操作。

在Task实体中为您的核心数据模型添加一个transient属性。然后实现

- (void)awakeFromFetch
任务NSManagedObject类中的

方法。查看其文档。在该方法中,您可以使用其他属性的值为transient属性设置值。请注意,对于您可以执行的操作存在一些限制,但在文档中对此进行了详细说明(最值得注意的是,您无法修改关系或传递参数;但是,如果您可以仅使用其他属性的值计算瞬态属性/关系应该非常好。)

完成此操作后,只需使用transient属性作为您传递的属性即可返回部分。

答案 2 :(得分:0)

这是一堆实现此目的的代码(感谢jbrennan):

@implementation NSDate (MyExtensions)


// Return today.
+ (NSDate *)today {

    return [NSDate date];
}


// Return yesterday (today minus 24 hours).
+ (NSDate *)yesterday {

    return [NSDate dateWithTimeIntervalSinceNow:-60*60*24];
}


// Return tomorrow (today plus 24 hours).
+ (NSDate *)tomorrow {

    return [NSDate dateWithTimeIntervalSinceNow:60*60*24];
}


// Convert a date comporting a time into a rounded date (just the day, no time).
- (NSDate *)dayDate {

    unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit;
    NSDateComponents *comps = [[NSCalendar currentCalendar] components:unitFlags fromDate:self];
    return [[NSCalendar currentCalendar] dateFromComponents:comps]; 
}


// Return a string representing the date relatively (today, tomorrow, yesterday, etc.)
// If no relative sentence is found, return the NSDateFormatterLongStyle formatted date.
- (NSString *)relativeDate {

    if ([self.dayDate isEqualToDate:[[NSDate today] dayDate]]) {

        return NSLocalizedString(@"Today", @"NSDate extensions");
    }
    if ([self.dayDate isEqualToDate:[[NSDate yesterday] dayDate]]) {

        return NSLocalizedString(@"Yesterday", @"NSDate extensions");
    }
    if ([self.dayDate isEqualToDate:[[NSDate tomorrow] dayDate]]) {

        return NSLocalizedString(@"Tomorrow", @"NSDate extensions");
    }

    return [NSDateFormatter localizedStringFromDate:self
                                          dateStyle:NSDateFormatterLongStyle
                                          timeStyle:NSDateFormatterNoStyle];    
}


@end