NSFetchedResultsController:重新排序部分
Posted
技术标签:
【中文标题】NSFetchedResultsController:重新排序部分【英文标题】:NSFetchedResultsController: ReOrder Sections 【发布时间】:2014-06-18 18:53:52 【问题描述】:我正在按照 Apple 的示例来设置我的部分:
https://developer.apple.com/library/ios/samplecode/DateSectionTitles/Listings/DateSectionTitles_APLEvent_m.html
我的部分目前按以下顺序显示:
Section 0: "Upcoming"
Section 1: "Today"
Section 2: "Past"
我在NSManagedObject
.m 文件中使用的代码:
#pragma mark - Transient properties
- (NSString *)sectionIdentifier
// Create and cache the section identifier on demand.
[self willAccessValueForKey:@"sectionIdentifier"];
NSString *tmp = [self primitiveSectionIdentifier];
[self didAccessValueForKey:@"sectionIdentifier"];
if (!tmp)
NSDate *dateToCompare = [self getUTCFormateDate:[self startDate]];
NSLog(@"********Date To Compare****** %@", dateToCompare);
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* now = [NSDate date];
NSDateFormatter *format = [[NSDateFormatter alloc] init];
format.dateFormat = @"dd-MM-yyyy";
NSString *stringDate = [format stringFromDate:now];
NSDate *todaysDate = [format dateFromString:stringDate];
NSInteger differenceInDays =
[calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSEraCalendarUnit forDate:dateToCompare] -
[calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSEraCalendarUnit forDate:todaysDate];
NSString *sectionString;
if (differenceInDays == 0)
sectionString = kSectionIDToday;
else if (differenceInDays < 0)
sectionString = kSectionIDPast;
else if (differenceInDays > 0)
sectionString = kSectionIDUpcoming;
tmp = sectionString;
[self setPrimitiveSectionIdentifier:tmp];
return tmp;
-(NSDate *)getUTCFormateDate:(NSDate *)localDate
NSDateFormatter *dateFormatter;
if (!dateFormatter)
dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
[dateFormatter setTimeZone:timeZone];
[dateFormatter setDateFormat:@"yyyy-MM-dd"];
NSString *dateString = [dateFormatter stringFromDate:localDate];
NSDate *dateFromString = [[NSDate alloc] init];
dateFromString = [dateFormatter dateFromString:dateString];
return dateFromString;
#pragma mark - Time stamp setter
- (void)setStartDate:(NSDate *)newDate
// If the time stamp changes, the section identifier become invalid.
[self willChangeValueForKey:@"startDate"];
[self setPrimitiveStartDate:newDate];
[self didChangeValueForKey:@"startDate"];
[self setPrimitiveSectionIdentifier:nil];
#pragma mark - Key path dependencies
+ (NSSet *)keyPathsForValuesAffectingSectionIdentifier
// If the value of timeStamp changes, the section identifier may change as well.
return [NSSet setWithObject:@"startDate"];
在我的 tableViewController 中,我将 NSFetchedResults 设置如下:
- (NSFetchedResultsController *)fetchedResultsController
if(_fetchedResultsController!=nil)
return _fetchedResultsController;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Entity"
inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *firstSort = [[NSSortDescriptor alloc] initWithKey:@"startDate"
ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc]initWithObjects:firstSort,nil];
[fetchRequest setSortDescriptors:sortDescriptors];
self.fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:@"sectionIdentifier"
cacheName:nil];
self.fetchedResultsController.delegate = self;
return self.fetchedResultsController;
问题 1:如何让这些部分按以下顺序显示:
Section 0: Today
Section 1: Upcoming
Section 2: Past
问题 2:在每个部分中,如何根据每个对象中名为 "modified"
的属性对行进行排序?
【问题讨论】:
【参考方案1】:节和行排序都 100% 取决于排序描述符。您希望您的第一个排序描述符将所有内容排序到正确的部分,然后您的后续排序描述符将对部分中的行进行排序。
例如,如果您想要基于“组”的三个部分,然后您想要在组内按名称排序的行,您可以将排序描述符添加为:
NSArray *descriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"group" ascending:YES], [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]];
[fetchRequest setSortDescriptors:descriptors];
NSFetchedResultsController
的分区键也需要与您的第一个 NSSortDescriptor
匹配。
【讨论】:
谢谢。所有对象都根据名为startDate
的属性进行排序。我如何让Today
的部分出现在Upcoming
之前。我是否需要创建另一个名为 sortKey
的瞬态属性并首先根据它进行排序?
是的,创建一个新键以在顶部进行排序,以将所有内容放入适当的部分。 NSSortDescriptor
实例需要非瞬态属性,因此您需要考虑设计的那部分...
我终于决定换个型号,加了一个sortKey
。但现在我遇到了另一个错误:CoreData: error: (NSFetchedResultsController) The fetched object at index 3 has an out of order section name ' Past. Objects must be sorted by section name'
我做了一个重复错误的示例项目:github.com/KausiAhmed/FRC
您的排序需要从您的sectionIdentifier
开始,然后您可以按其他任何内容进行排序。但第一个NSSortDescriptor
必须与sectionNameKeyPath
匹配。
感谢您查看代码!我一直在关注 Apple 的代码,它具有 sectionIdentifier
作为 transient
属性,并且它不基于 sectionNameKeyPath
排序:developer.apple.com/library/ios/samplecode/DateSectionTitles/… 我应该将其更改为非瞬态属性吗?我在想也许为每个部分做一个单独的 FRC?以上是关于NSFetchedResultsController:重新排序部分的主要内容,如果未能解决你的问题,请参考以下文章