核心数据按格式化日期排序表格视图
Posted
技术标签:
【中文标题】核心数据按格式化日期排序表格视图【英文标题】:Core Data sort tableview by formatted date 【发布时间】:2012-06-19 13:38:35 【问题描述】:我知道如何通过 NsDate 对 tableview 中的 Core Data 对象进行排序,但默认情况下这似乎为每个对象创建了一个新部分。我想用 NSDateFormatter 按中等格式的日期对它们进行排序。我该怎么做?
例如,如果我在同一天创建了 3 个对象,我希望它们位于同一节中,节标题为当天,不需要时间。
每个对象都有一个 NSDate 属性。感谢您的帮助。
这是我在 fetchedResultsController 中的代码以及 rgeorge 的建议。我在这里错过了什么?
- (NSFetchedResultsController *)fetchedResultsController
if (fetchedResultsController != nil)
NSLog(@"get old fetched controller");
return fetchedResultsController;
else
NSLog(@"get new fetched controller");
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"InTextEntity" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
NSSortDescriptor *dateDescriptor = [[NSSortDescriptor alloc] initWithKey:@"dateModified" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:dateDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"mediumFormattedDate" cacheName:@"Root"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
NSError *error = nil;
if (![fetchedResultsController performFetch:&error])
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
return fetchedResultsController;
【问题讨论】:
【参考方案1】:(假设您使用NSFetchedResultsController
来驱动您的tableview,我会写这篇文章。如果您不是,我建议您检查一下。)
NSFetchedResultsController
的分段功能的一个有趣特性:虽然您排序 的属性必须是建模属性(因为 sqlite 进行实际排序),但您分组的属性带有 的部分不需要。唯一的要求是分组与排序一致。 (即,按 sort 属性排序会将具有匹配组属性的对象彼此相邻。)
因此,只需在您的建模对象类中添加类似这样的内容:
// in interface
@property (nonatomic, readonly) NSString *mediumFormattedDate;
// in impl
-(NSString *)mediumFormattedDate
// this can be fancier if you need a custom format or particular timezone:
return [NSDateFormatter localizedStringFromDate:self.date
dateStyle:NSDateFormatterMediumStyle
timeStyle:NSDateFormatterNoStyle];
(根本不需要在 .xcdatamodel 中提及 mediumFormattedDate。)
然后继续按日期属性对对象进行排序,但按新属性对它们进行分组。创建NSFetchedResultsController
时,请按照以下方式进行:
NSFetchRequest *fr = [NSFetchRequest fetchRequestWithEntityName:@"MyFancyEntity"];
NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey:@"date"
ascending:YES];
[fr setSortDescriptors:[NSArray arrayWithObject:sd]];
NSFetchedResultsController *frc =
[[NSFetchedResultsController alloc] initWithFetchRequest:fr
managedObjectContext:myManagedObjectContext
sectionNameKeyPath:@"mediumFormattedDate"
cacheName:nil];
// then do stuff with frc
这就是全部!我已经在一些应用程序中完成此操作以获取日期分组,并且效果很好。
【讨论】:
非常感谢!我会在早上试试这个,让你知道结果如何! 一个问题,mediumFormattedDate中self.date的值是怎么设置的? 这是我得到的错误:实体 InTextEntity 不符合键“mediumFormattedDate”的键值编码。' 听起来好像您的 InTextEntity 实例实际上并不是您添加 mediumFormattedDate: 到的任何类的实例?检查您的 xcdatamodel。我应该提到这种技术需要自定义实体类——使用普通的 NSManagedObjects 是行不通的。如果没有更多细节,我不能说更多。 对于“self.date”:“self”是托管对象,“date”是对您排序依据的日期属性名称的猜测。替换为您使用的实际名称。【参考方案2】:听起来您将获取结果控制器上的部分索引设置为您的日期属性,这似乎是不可取的。
相反,您可能应该自己计算节索引,并按日期排序。您可以在数据模型中或通过在代码中手动计算部分来完成此操作。
例如,您可以向托管对象模型添加一个名为“Day”的属性,并将其设置为您想要使用的任何值(您无需指定它是像星期一还是像 21 这样的实际日期)。
然后您可以将该属性传递给获取的结果控制器。
或者您可以自己实施这些部分,日子很容易,周一至周日。日期有点难,1-28,30,31 取决于月份。然后使用适当的 NSPredicate / NSFetchRequest 来获取每个部分中的项目数。
【讨论】:
以上是关于核心数据按格式化日期排序表格视图的主要内容,如果未能解决你的问题,请参考以下文章