NSFetchedResultsController и UILocalizedIndexCollation

Я хочу заселить UITableView с помощью NSFetchedResultsController, Я хочу, чтобы в табличном представлении были разделы для первой буквы в названии объекта. Табличное представление также должно иметь индексный список справа.

Вот как выглядит моя сущность:

@interface Book : NSManagedObject

@property (nonatomic, copy) NSString *title;

@end

Мой первый план состоял в том, чтобы иметь временное свойство, которое возвращало первую букву в заголовке:

- (NSString *)firstLetter
{
    // Edge-cases checking code not included
    return [self.title substringToIndex:1];
}

Проблема в том, что он даст вам разные разделы для "2" и "3", например, я хочу, чтобы все цифры и символы в одном разделе назывались "#", так же, как UILocalizedIndexCollation дает тебе.

Но какие буквы должны быть в категории "#"? Конечно, это зависит от языка, на английском языке "Ö" должно быть в другой категории, но на шведском языке это должно быть в своей собственной категории. Поэтому я подумал, что, может быть, я должен просто использовать NSLocalizedIndexCollation вместо. Вот этот код:

- (void)recalculateSectionizedBooks
{
    SEL selector = @selector(title);
    NSInteger sectionTitlesCount = [[[UILocalizedIndexedCollation currentCollation] sectionTitles] count];

    NSMutableArray *mutableSections = [NSMutableArray arrayWithCapacity:sectionTitlesCount];
    for (NSUInteger idx = 0; idx < sectionTitlesCount; idx++)
    {
        [mutableSections addObject:[NSMutableArray array]];
    }

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Book"];
    NSError *error = nil;
    NSArray *result = [self.context executeFetchRequest:request
                                                  error:&error];
    if (error)
    {
        NSLog(@"Error fetching: %@", error);
    }

    for (Book *book in result)
    {
        NSInteger sectionNumber = [[UILocalizedIndexedCollation currentCollation] sectionForObject:book
                                                                           collationStringSelector:selector];
        [mutableSections[sectionNumber] addObject:book];
    }

    for (NSUInteger idx = 0; idx < sectionTitlesCount; idx++)
    {
        NSArray *objectsForSection = mutableSections[idx];
        mutableSections[idx] = [[UILocalizedIndexedCollation currentCollation] sortedArrayFromArray:objectsForSection
                                                                            collationStringSelector:selector];
    }

    self.sectionizedBooks = mutableSections;
}

Это называется в -viewWillAppear:после этого я перезагружаю свой вид таблицы. Метод источника данных правильно настроен, а также обеспечивает отсутствие пустых разделов.

Это решение имеет две проблемы. Во-первых, для работы требуется огромное количество кода (гораздо больше, чем фрагмент, который я вам показал). Вторая, более серьезная проблема заключается в том, что производительность очень плохая. Каждый раз, когда представление отображается, разделы должны быть пересчитаны, потому что что-то, влияющее на это, могло измениться. Это заняло 30 секунд с 10 тысячами книг, что недопустимо.

Я думаю, что мне нужно решение, которое сочетает в себе NSFetchedResultsController а также UILocalizedCollation умным способом. Вот что мне нужно из решения:

  • Наличие книг в разделах на основе первой буквы в заголовке
  • "Другая" категория ('#') должна существовать в конце
  • Нет пустых разделов
  • Индексный список справа со всеми возможными буквами + '#' в конце
  • Высокая производительность, по крайней мере, после первого просмотра

0 ответов

Другие вопросы по тегам