Поскольку, похоже, никто не мог предложить решение, я думал, что опубликую решение, которое я придумал. Во-первых, я создал модель для моих данных:
@interface MyModel : NSObject
{
NSString* _value;
NSString* _sortableValue;
}
@property (nonatomic,copy) NSString* value;
- (NSString*)sortableValue;
- (NSString*)comparableString:(NSString*)str;
@end
Они ключ к модели является метод comparableString, который привыкает для создания sortableValue. Вот реализация модели:
@implementation MyModel
@synthesize value=_value;
-(void)dealloc
{
[_value release];
[_sortableValue release];
[super dealloc];
}
- (void)setValue:(NSString*)value
{
[_value release];
_value = [value copy];
[_sortableValue release];
_sortableTValue = nil;
}
- (NSString*)sortableValue
{
if (_sortableValue == nil)
_sortableValue = [[self comparableString:_value] retain];
return _sortableValue;
}
- (NSString*)comparableString:(NSString*)str
{
if (str == nil)
return nil;
else if ([str length] == 0)
return [NSString stringWithString:str];
NSCharacterSet* numbersSet = [NSCharacterSet decimalDigitCharacterSet];
if ([str rangeOfCharacterFromSet:numbersSet options:0 range:NSMakeRange(0, 1)].location != NSNotFound)
return [NSString stringWithString:str];
NSRange range = NSMakeRange(0, [str length]);
if ([str compare:@"a " options:(NSAnchoredSearch|NSCaseInsensitiveSearch) range:NSMakeRange(0, 2)] == NSOrderedSame)
range.location = 2;
else if ([str compare:@"an " options:(NSAnchoredSearch|NSCaseInsensitiveSearch) range:NSMakeRange(0, 3)] == NSOrderedSame)
range.location = 3;
else if ([str compare:@"the " options:(NSAnchoredSearch|NSCaseInsensitiveSearch) range:NSMakeRange(0, 4)] == NSOrderedSame)
range.location = 4;
range.length -= range.location;
NSCharacterSet* lettersSet = [NSCharacterSet letterCharacterSet];
NSUInteger letterOffset = [str rangeOfCharacterFromSet:lettersSet options:0 range:range].location;
if (letterOffset == NSNotFound)
return [NSString stringWithString:str];
letterOffset -= range.location;
range.location += letterOffset;
range.length -= letterOffset;
return [str substringWithRange:range];
}
@end
В дополнении к удаляющим ведущим статьям из строки, он также удаляет любые ведущие символы небуквенных. У меня есть песня в моей библиотеке iPod под названием «$ ell Your $ oul», которая заканчивается в разделе E в MPMediaPickerController. Я не уверен, что это то, что я бы сделал, если бы я обработал исходный алгоритм сортировки, но я собирался согласовать с MPMediaPickerController, так что вы идете.
Последним головоломкой является класс UILocalizedIndexedCollation. Этот удобный небольшой вспомогательный класс поможет вам отсортировать данные, чтобы обеспечить его подключение к UITableView через UITableViewDataSource куском пирога. Вот отрывок о том, как использовать класс UILocalizedIndexedCollation в сочетании с моделью:
// tableData will contain an NSArray for each populated section in the table view
NSMutableDictionary* tableData = [NSMutableDictionary dictionary];
NSMutableArray* myArray = [NSMutableArray array];
// Populate myArray with instances of MyModel
UILocalizedIndexedCollation* indexer = [UILocalizedIndexedCollation currentCollation];
for (MyModel* data in myArray)
{
NSInteger index = [indexer sectionForObject:data collationStringSelector:@selector(sortableValue)];
NSNumber* key = [[NSNumber alloc] initWithInteger:index];
NSMutableArray* array = [tableData objectForKey:key];
if (array == nil)
{
array = [NSMutableArray new]; // Will be released after creating a sorted array in the following section
[tableData setObject:array forKey:key];
}
[array addObject:data];
[key release];
}
[tableData enumerateKeysAndObjectsUsingBlock:^(id key, id array, BOOL* stop)
{
NSMutableArray* sortedArray = [[indexer sortedArrayFromArray:array collationStringSelector:@selector(sortableValue)] mutableCopy];
[tableData setObject:sortedArray forKey:key];
[array release];
}];
Одно быстрое примечание о UILocalizedIndexedCollation (из документации компании Apple):
Если приложение содержит файл Localizable.strings для нужного языка , объект индексированного сопоставления локализует каждую строку, возвращаемую методом , идентифицированную селектором.
Поэтому убедитесь, что вы предоставили Localizable.strings для каждого языка, который хотите поддерживать, или в вашем представлении таблицы будут только разделы A-Z и #.
Мне потребовалось некоторое время, чтобы разобраться во всех подробностях, поэтому я надеюсь, что это станет полезным для других людей. Если вы видите какие-либо способы улучшить это, пожалуйста, дайте мне знать!
+1 Отличный рабочий человек. Однажды я видел ур, но у меня нет времени, чтобы найти решение. Хорошая работа. – KingofBliss
Удивительный ответ. Не могли бы вы предложить, как я могу реализовать это с помощью 'MPMediaQuery'? Как бы включить это в класс 'UITableViewController', мне нужно было бы создать отдельный массив со списком букв для разделов? – sooper