Использование пользовательских разделов с NSFetchedResultsController?
Я делаю секционированную таблицу с извлеченными результатами, но мне сложно сработать настраиваемые разделы.
Как правило, просто нужно иметь атрибут для сортировки и использовать sectionNameKeyPath:
для генерации разделов. Но мой атрибут сортировки вычисляется "на лету", и я не могу заставить fetchedResultsController
использовать его правильно...
Обновление: Используя jbrennan ниже, я действительно близок к предполагаемой функциональности. Я добавил категорию в NSDate
, которая возвращает число "дней назад"; введя здесь здесь, вы получите разделы, основанные на этих числах:
NSFetchedResultsController *aFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:@"myDateAttribute.daysAgo"
cacheName:@"Root"];
Здесь, где я застрял: мне не нужны они отсортированы "днями назад", они мне нужны, они отсортированы с помощью некоторых вычислений на основе других атрибутов в сущности. Поэтому я не могу просто вызвать этот настраиваемый метод Category, мне нужно вызвать метод с аргументами, например:
[myDateAttribute sortingRoutine:thisObject.value]
Или что-то в этом роде. Надеюсь, это имеет определенный смысл. Спасибо, если вы можете помочь:)
Ответы
Ответ 1
Вы можете попробовать следующее.
Добавить переходный атрибут в вашу основную модель данных в объекте Task. Затем выполните
- (void)awakeFromFetch
в классе Task NSManagedObject. См. Его документацию. В рамках метода вы можете установить значение для свойства переходного процесса, используя значения других свойств. Обратите внимание, что есть некоторые ограничения на то, что вы можете сделать, но это хорошо объяснено в документации (в частности, вы не можете изменять отношения или передавать аргументы, однако, если вы можете вычислить свойство переходного процесса, используя только значения других свойств/отношения это должно быть прекрасно).
Как только вы это сделаете, вы просто используете свойство переходного процесса как атрибут, который вы передаете, чтобы вернуть разделы.
Ответ 2
Я сделал что-то подобное этому в (скоро появляющемся) доставке iPhone-приложения. Мои разделы были разделены по датам следующим образом: вчера, сегодня, завтра, в будущем...
В любом случае, трюк для меня заключался в добавлении категории в NSDate для определения того, в каком разделе принадлежал мой импортированный объект.
У моего управляемого объекта было свойство, называемое dueDate, которое было NSDate. При настройке контроллера получаемых результатов я использовал @"dueDate.relativeDate"
как путь к разделу раздела.
В категории -relativeDate
было объявлено как возвращающее NSString
, а также как свойство readonly
(одного из которых может быть достаточно, я не пробовал, не имея обоих, но это не мешает иметь как метод, так и объявление свойств). Затем я просто реализовал метод, при котором он работал красиво.
Ответ 3
Вот куча кода для этого (спасибо jbrennan):
@implementation NSDate (MyExtensions)
// Return today.
+ (NSDate *)today {
return [NSDate date];
}
// Return yesterday (today minus 24 hours).
+ (NSDate *)yesterday {
return [NSDate dateWithTimeIntervalSinceNow:-60*60*24];
}
// Return tomorrow (today plus 24 hours).
+ (NSDate *)tomorrow {
return [NSDate dateWithTimeIntervalSinceNow:60*60*24];
}
// Convert a date comporting a time into a rounded date (just the day, no time).
- (NSDate *)dayDate {
unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents *comps = [[NSCalendar currentCalendar] components:unitFlags fromDate:self];
return [[NSCalendar currentCalendar] dateFromComponents:comps];
}
// Return a string representing the date relatively (today, tomorrow, yesterday, etc.)
// If no relative sentence is found, return the NSDateFormatterLongStyle formatted date.
- (NSString *)relativeDate {
if ([self.dayDate isEqualToDate:[[NSDate today] dayDate]]) {
return NSLocalizedString(@"Today", @"NSDate extensions");
}
if ([self.dayDate isEqualToDate:[[NSDate yesterday] dayDate]]) {
return NSLocalizedString(@"Yesterday", @"NSDate extensions");
}
if ([self.dayDate isEqualToDate:[[NSDate tomorrow] dayDate]]) {
return NSLocalizedString(@"Tomorrow", @"NSDate extensions");
}
return [NSDateFormatter localizedStringFromDate:self
dateStyle:NSDateFormatterLongStyle
timeStyle:NSDateFormatterNoStyle];
}
@end