所以我有这个自定义生成的数组来定义UITableView
的部分,但正如您所看到的,所有项目都是通过Core Data获取并单独排序的。
这是我的自定义代码:
-(NSArray *)tasks {
NSManagedObjectContext *managedObjectContext = [self.fetchedResultsController managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Task" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
// retrive the objects with a given value for a certain property
[request setPredicate:nil];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"scheduledDate" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"];
aFetchedResultsController.delegate = self;
NSError *error = nil;
NSArray *result = [managedObjectContext executeFetchRequest:request error:&error];
if ((result != nil) && ([result count]) && (error == nil)){
return [NSMutableArray arrayWithArray:result];
}
return [NSMutableArray array];
}
-(NSMutableArray *)sectionsArray {
// Fetch the scheduledDate check if it is in any of the term arrays and dump it in that section.
NSArray *tasks = [self tasks];
if (tasks) {
NSArray *scheduledTasks = [tasks valueForKey:@"scheduledDate"];
scheduledTasks = [[[NSSet setWithArray:scheduledTasks] allObjects] sortedArrayUsingSelector:@selector(compare:)];
NSMutableArray *shortTermTasks = [NSMutableArray array];
NSMutableArray *midTermTasks = [NSMutableArray array];
NSMutableArray *longTermTasks = [NSMutableArray array];
for (NSDate *scheduledDate in scheduledTasks) {
NSString *dateString = [NSString dateStringFromFullDate:scheduledDate];
NSPredicate *pred = [NSPredicate predicateWithFormat:@"scheduledDate == %@", scheduledDate];
NSManagedObject *task = [[tasks filteredArrayUsingPredicate:pred] lastObject];
if ([[self shortTermDateStrings] containsObject:dateString]) {
[shortTermTasks addObject:task];
}
if ([[self midTermDateStrings] containsObject:dateString]) {
[midTermTasks addObject:task];
}
if ([[self longTermDateStrings] containsObject:dateString]) {
[longTermTasks addObject:task];
}
}
sectionsArray = [NSMutableArray arrayWithObjects:shortTermTasks,midTermTasks,longTermTasks, nil];
return sectionsArray;
}
return [NSMutableArray array];
}
我研究并发现(NSFetchedResultsController *)fetchedResultsController
定义了各个部分的组织方式,现在的问题是如何在这里生成自定义数组。
我的(NSFetchedResultsController *)fetchedResultsController
看起来像这样:
- (NSFetchedResultsController *)fetchedResultsController
{
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Task" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Set the batch size to a suitable number.
[fetchRequest setFetchBatchSize:20];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"scheduledDate" ascending:YES];
NSArray *sortDescriptors = @[sortDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _fetchedResultsController;
}
更新:根据shortTerm
中的midTerm
生成longTerm
,[NSDate date]
和sectionIdentifier
日期的代码
注意:我为此制作了很多NSDate
和NSString
类别。
-(NSArray *)shortTermDates {
NSArray *fullDateList = [NSDate daysFrom:[NSDate date] to:[NSDate dateWithDaysFromNow:2]];
NSMutableArray *daysList = [NSMutableArray array];
NSString *dateString = nil;
for (NSDate *date in fullDateList) {
dateString = [NSString dateStringFromFullDate:date];
[daysList addObject:dateString];
}
return fullDateList;
}
-(NSArray *)shortTermDateStrings {
NSMutableArray *daysList = [NSMutableArray array];
NSString *dateString = nil;
for (NSDate *date in [self shortTermDates]) {
dateString = [NSString dateStringFromFullDate:date];
[daysList addObject:dateString];
}
return daysList;
}
-(NSArray *)midTermDates {
NSDate *startDate = [[self shortTermDates] lastObject];
int addition = 5;
int dayFromLastTermDate = [NSDate extractDayFromDate:[[self shortTermDates] lastObject]];
NSDate *date = [NSDate dateWithYear:[NSDate extractYearFromDate:startDate] month:[NSDate extractMonthFromDate:startDate] day:dayFromLastTermDate+addition hour:[NSDate extractHourFromDate:startDate] minute:[NSDate extractMinuteFromDate:startDate] second:[NSDate extractSecondFromDate:startDate]];
NSArray *fullDateList = [NSDate daysFrom:startDate to:date];
return fullDateList;
}
-(NSArray *)midTermDateStrings {
NSMutableArray *daysList = [NSMutableArray array];
NSString *dateString = nil;
for (NSDate *date in [self midTermDates]) {
dateString = [NSString dateStringFromFullDate:date];
[daysList addObject:dateString];
}
return daysList;
}
-(NSArray *)longTermDates {
NSDate *startDate = [[self midTermDates] lastObject];
int addition = 8;
int dayFromLastTermDate = [NSDate extractDayFromDate:[[self midTermDates] lastObject]];
NSDate *date = [NSDate dateWithYear:[NSDate extractYearFromDate:startDate] month:[NSDate extractMonthFromDate:startDate] day:dayFromLastTermDate+addition hour:[NSDate extractHourFromDate:startDate] minute:[NSDate extractMinuteFromDate:startDate] second:[NSDate extractSecondFromDate:startDate]];
NSArray *fullDateList = [NSDate daysFrom:startDate to:date];
return fullDateList;
}
-(NSArray *)longTermDateStrings {
NSMutableArray *daysList = [NSMutableArray array];
NSString *dateString = nil;
for (NSDate *date in [self longTermDates]) {
dateString = [NSString dateStringFromFullDate:date];
[daysList addObject:dateString];
}
return daysList;
}
- (NSString *)sectionIdentifier;
{
NSDate *date = self.scheduledDate;
if ([date compare:[[self shortTermDates] lastObject]] == NSOrderedAscending) {
return @"0";
if ([date compare:[[self midTermDates] lastObject]] == NSOrderedAscending) {
return @"1";
} else {
return @"2";
}
}
return nil;
}
答案 0 :(得分:3)
将表视图分组为具有获取结果控制器(FRC)的部分需要两件事:
sectionNameKeyPath:
。这可以是实体的任何属性(持久性或瞬态),甚至是任意实例方法
托管对象子类。sectionNameKeyPath:
属性/方法相同的相对排序。此排序描述符只能使用
实体的持久属性。您已根据scheduledDate
属性对对象进行了排序。分组
将对象分成几个部分,您只需要向托管添加“合适的”实例方法
对象子类。
我们假设您有一些日期变量shortTermLimit
和midTermLimit
。
然后,您可以在您的类类别中定义以下方法
托管对象子类:
@implementation Task (CategoryMethods)
- (NSString *)sectionIdentifier;
{
NSDate *date = self.scheduledDate;
if ([date compare:shortTermLimit] == NSOrderedAscending) {
return @"0";
} else if ([date compare:midTermLimit] == NSOrderedAscending) {
return @"1";
} else {
return @"2";
}
}
@end
然后使用参数
创建FRCsectionNameKeyPath:@"sectionIdentifier"
现在,shortTermLimit
之前安排的所有任务都被分组到“0”部分,
在midTermLimit
之前安排的任务被分组到“1”部分,
其余任务分为“2”部分。
请注意,相对排序(“0”,“1”,“2”)与排序描述符兼容
使用scheduledDate
。
但是你不希望“0”,“1”,“2”作为章节标题,所以剩下的就是修改
titleForHeaderInSection
委托方法:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
NSString *name = [sectionInfo name];
if ([name isEqualToString:@"0"]) {
return @"Short Term";
} else if ([name isEqualToString:@"1"]) {
return @"Mid Term";
} else {
return @"Long Term";
}
}
还可以查看Apple Developer Library中的"DateSectionTitles"示例项目,其工作方式类似于 按年份和月份将对象分组。
答案 1 :(得分:0)
向您的Task
实体添加一个瞬态属性,称之为sectionName
。保存实体或设置scheduledDate
时,计算新的sectionName
并存储它。将sectionName
设置为FRC使用的关键路径。