我有UITableViewController
使用NSFetchedResultsController
显示列表。
这是myObject的列表,并具有属性date
。
我创建了一个方法- (NSFetchedResultsController *)fetchedResultsController
来获取按日期排序的所有条目。
结果如下:
在此之后我添加了- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
,以便时间+日期显示在dateStyle:NSDateFormatterMediumStyle
中。
如下图所示,您可以看到日期打印正确,但2014年3月12日的2行和2014年3月14日的其他2行未组合在一起。
我的猜测是我需要更改numberOfSectionsInTableView
方法,因为它仍在查看日期+时间,而不仅仅是日期,但我不知道如何。
我的代码:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSInteger count = [[self.fetchedResultsController sections] count];
return count;
}
一种可能性是在我的对象中添加一个属性,例如“sectionIdentifier”'仅存储日期并使用它。我想知道是否有人知道如何处理这个问题。是否可以将这些日期组合在一起,我将代码添加到- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
?
答案 0 :(得分:2)
在Swift 4.2中得出答案。
有两个步骤:
步骤1:在extension
上创建NSManagedObject
(示例使用Entry
作为托管对象),并使用@objc
公开它:
extension Entry {
@objc var isoDate: String { get {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
// insert settings for TimeZone and Calendar here
return formatter.string(from: Entry.date!)
}}
}
步骤2:使用属性isoDate
作为sectionNameKeyPath
的值:
let fetchedResultController = NSFetchedResultsController(fetchRequest: expenseFetchRequest(),
managedObjectContext: coreDataStack.mainContext,
sectionNameKeyPath: #keyPath(Expense.dateISO),
cacheName: nil)
现在,您的FRC应该可以将对象分成几部分了!
答案 1 :(得分:1)
我喜欢用FRC控制它,如果想要不同/自定义功能,请保留委托调用来更改它。我还认为FRC通常应该被构建为被观察实体的类方法。
您可以使格式化的字符串成为对象的完整属性,但这似乎很浪费。
你也可以使它成为一个真正的瞬态属性。这可能更合适,但我使用的是现有模型,并且不想更改模型。自那个项目以来,我对其他任何类似的案例都采用了这种方法。
无论如何,这个例子几乎都是从现有应用程序中直接获取的。我不得不改变一些事情,所以我希望我没有遗漏任何东西。
创建FRC使用的获取请求,以便根据对象的date
属性进行排序。这允许在标准属性上获取正常的核心数据。
+ (NSFetchedResultsController *)
fetchedResultsController:(NSManagedObjectContext *)context
{
NSFetchRequest* request = [NSFetchRequest
fetchRequestWithEntityName:[self entityName]];
request.sortDescriptors = @[[NSSortDescriptor
sortDescriptorWithKey:@"date"
ascending:YES]];
request.fetchBatchSize = 30;
request.returnsObjectsAsFaults = NO;
NSString *cacheName = [[self entityName]
stringByAppendingString:@"-all-bydate"];
return [[NSFetchedResultsController alloc]
initWithFetchRequest:request
managedObjectContext:context
sectionNameKeyPath:@"dateAsSectionName"
cacheName:cacheName];
}
将一个实例变量添加到您的子类......您将自己管理它......
@implementation MyManagedObjectSubclass {
NSString *dateAsSectionName_;
}
添加访问者方法。我们只创建一次格式化程序。根据自己的喜好改变它。
- (NSString*)dateAsSectionName
{
static NSDateFormatter *dateFormatter;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = @"EEE, MMM d, h:mm a";
dateFormatter.dateFormat = @"EEEE MMMM d";
});
if (dateAsSectionName_ == nil) {
NSDate *date = [self primitiveDate];
dateAsSectionName_ = [dateFormatter stringFromDate:date];
}
return dateAsSectionName_;
}
当日期更改时清除我们的部分名称,因此我们将在下次调用访问者时重新计算其值。
- (void)setDate:(NSDate*)date
{
if ([[self primitiveDate] isEqualToDate:date]) return;
[self willChangeValueForKey:@"date"];
[self setPrimitiveDate:date];
[self didChangeValueForKey:@"date"];
dateAsSectionName_ = nil;
}
告诉KVO dateAsSectionName
取决于date
。
+ (NSSet *)keyPathsForValuesAffectingDateAsSectionName
{
return [NSSet setWithObject:@"date"];
}
答案 2 :(得分:0)
阅读这两篇文章,添加属性似乎就是答案