Core Data sort tableview by formatted date

我与影子孤独终老i 提交于 2019-12-08 06:08:48

问题


I know how to sort Core Data objects in a tableview by NsDate, but this by default seems to create a new section for each object. I want to sort them by a medium formatted date with NSDateFormatter. How would I do this?

For example, if I have 3 objects created on the same day, I want them to be in the same section with the section title being that Day, no time needed.

Each object has an NSDate property. Thanks for your help.

This is the code I have in fetchedResultsController with rgeorge's suggestions. What am I missing here?

- (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:


(I'll write this up assuming you're using an NSFetchedResultsController to drive your tableview. If you're not, I recommend checking it out.)

An interesting feature of NSFetchedResultsController's sectioning abilities: although the property you sort on must be a modeled property (because sqlite does the actual sorting), the property you group the sections with need not be. The only requirement is that the grouping be consistent with the ordering. (i.e., sorting by the sort property will put the objects with matching group properties next to each other.)

So just add something like this to your modeled object class:

// 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];
}

(no need to mention mediumFormattedDate in the .xcdatamodel at all.)

Then go ahead and sort your objects by the date property, but group them by your new property. When you create your NSFetchedResultsController, do so along these lines:

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

That's all it takes! I've done this in a few apps to get date grouping and it works well.




回答2:


Sounds like you're setting the section index on the fetched results controller to be your date property, which seems undesirable.

Instead you should probably be computing the section index yourself, and sorting by date. You can accomplish this in either your data model or by computing the sections manually in code.

For example, you could add a property to your managed object model called "Day" and set that to whatever value you want to use (you don't specify if its something like Monday or an actual date like 21).

You can then pass that property to the fetched results controller.

Alternatively you could implement the sections yourself, days are easy, its Monday-Sunday. Dates are a bit harder, 1-28,30,31 depending on what month it is. Then use an appropriate NSPredicate / NSFetchRequest to get the count of the items in each section.



来源:https://stackoverflow.com/questions/11102174/core-data-sort-tableview-by-formatted-date

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!