2009-08-12 1 views
1

У меня есть plist, который содержит массив с набором словарей. Словари в массиве используются для создания довольно сложного представления таблицы с двумя изображениями и двумя строками текста в каждой ячейке. Я хочу создать разделы в представлении таблицы на основе первой буквы для значения, соответствующего клавише «MainText».Лучший способ захватить массив словарей из plist и создать разделы на основе значений для ключа

Формат plist. В этом примере должно быть 2 раздела, один для словаря со строкой «MainText», начинающийся с «A», и один для 2 словарей с строками «MainText», начиная с «B».

<dict> 
<key>Rows</key> 
<array> 
    <dict> 
     <key>MainText</key> 
     <string>A sometext</string> 
     <key>SecondaryText</key> 
     <string>somemoretext</string> 
     <key>PrimaryIcon</key> 
     <string>firsticon.png</string> 
     <key>SecondaryIcon</key> 
     <string>secondicon.png</string> 
    </dict> 
    <dict> 
     <key>MainText</key> 
     <string>B sometext</string> 
     <key>SecondaryText</key> 
     <string>somemoretext</string> 
     <key>PrimaryIcon</key> 
     <string>firsticon.png</string> 
     <key>SecondaryIcon</key> 
     <string>secondicon.png</string> 
    </dict> 
      <dict> 
     <key>MainText</key> 
     <string>B moreTextStartingWith"B"</string> 
     <key>SecondaryText</key> 
     <string>somemoretext</string> 
     <key>PrimaryIcon</key> 
     <string>firsticon.png</string> 
     <key>SecondaryIcon</key> 
     <string>secondicon.png</string> 
    </dict> 
</array> 

Я написал код для извлечения первых букв из строки в ключе «MainText», сортируя их и создавать заголовки разделов. У меня также есть код для установки правильного количества строк в каждом разделе. Вот некоторые из кода, с которым я запутался в моем методе viewDidLoad.

//Create an array sorted by the strings in "MainText" of the AppDelegate.data 
    NSSortDescriptor *sortDescriptor; 
    sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"MainText" ascending:YES] autorelease]; 
    NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor]; 
    NSArray *sortedArray; 
    sortedArray = [[AppDelegate.data objectForKey:@"Rows"] sortedArrayUsingDescriptors:sortDescriptors]; 


//Now set tableDataSource equal to sortedArray 
    self.tableDataSource = sortedArray; 

//Create a set of the first letters used by the strings in MainText 
    NSMutableSet *firstCharacters = [NSMutableSet setWithCapacity:0]; 
    for(NSString *string in [tableDataSource valueForKey:@"MainText"]) 
     [firstCharacters addObject:[string substringToIndex:1]]; 

//Create a sorted array of first letters used by strings in MainText 
    self.arrayOfInitialLetters = [[firstCharacters allObjects] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; 

//Create an array of the MainText of each item in tableDataSource 
    NSMutableArray * mainTextArray = [tableDataSource valueForKey:@"MainText"]; 

Как я должен идти о получении правильных строк в моем методе cellForRowAtIndexPath? В настоящее время в каждом разделе отображаются одни и те же ячейки, начиная с первого. Мне нужно как-то определить в моем источнике данных, что есть разные разделы. Спасибо за помощь, это была настоящая борьба!

+0

В вашем PLIST я полагаю, что следует читать со вторым закрытием и что должен быть на end? ... – h4xxr

+0

Да, это так. Он должен быть потерян в копии. Я исправил его выше. – Jonah

ответ

1

Я, наконец, получил эту работу. Вот код для моего метода viewDidLoad. Это может быть не самый чистый метод для получения моего результата, но он отлично работает! Тем не менее, я приветствую любые предложения.

- (void)viewDidLoad { 
[super viewDidLoad]; 

// Load the UICustomTabViewController 
    UICustomTabViewController *tvController = [[UICustomTabViewController alloc] 
     initWithNibName:@"TabViewController" bundle:nil]; 
    self.tabViewController = tvController; 
    [tvController release]; 

    YourAppDelegate *AppDelegate = (YourAppDelegate *)[[UIApplication 
     sharedApplication] delegate]; 


// Create an array sorted by CommonName of the AppDelegate.data 
    NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"CommonName" ascending:YES] autorelease]; 
    NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor]; 
    NSArray *sortedArray; 
    sortedArray = [[AppDelegate.data objectForKey:@"Rows"] sortedArrayUsingDescriptors:sortDescriptors]; 

// Now set tableDataSource equal to sortedArray 
    self.tableDataSource = sortedArray; 

// Create a set of the first letters used by the strings in CommonName and sort them 
    NSMutableSet *firstCharacters = [NSMutableSet setWithCapacity:0]; 
    for(NSString *string in [tableDataSource valueForKey:@"CommonName"]) 
     [firstCharacters addObject:[string substringToIndex:1]]; 
     self.arrayOfInitialLetters = [[firstCharacters allObjects] 
     sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; 

    self.sectionedDictionaryByFirstLetter = [NSMutableDictionary dictionary];   

// All data sorted in sections by initial letter of "CommonName" 
    NSDictionary *eachItemList; //PUTS ALL THE DATA FOR EACH ITEM IN IT'S OWN SECTION 
    for (eachItemList in tableDataSource) //eachElementList is an array with a section for each item 
    { 
     NSDictionary *aDictionary = [[NSDictionary alloc] initWithDictionary:eachItemList]; 
     NSString *firstLetterString; 
     firstLetterString = [[aDictionary valueForKey:@"CommonName"]substringToIndex:1]; 

     NSMutableArray *existingArray; 

     if (existingArray = [sectionedDictionaryByFirstLetter valueForKey:firstLetterString]) 
     { 
      [existingArray addObject:eachItemList]; 
     } else { 
      NSMutableArray *tempArray = [NSMutableArray array]; 
      [sectionedDictionaryByFirstLetter setObject:tempArray forKey:firstLetterString]; 
      [tempArray addObject:eachItemList]; 
     } 
     [aDictionary release]; 
     [eachItemList release]; 
     NSLog(@"nameIndexesDictionary:%@", sectionedDictionaryByFirstLetter); 
    } 

Тогда это, как я был в состоянии получить правильную строку в моем методе cellForRowAtIndexPath

NSInteger section = [indexPath section]; 
    NSString *key = [arrayOfInitialLetters objectAtIndex:section]; 
    NSArray *nameSection = [sectionedDictionaryByFirstLetter objectForKey:key]; 
    NSDictionary *dictionary = [nameSection objectAtIndex:indexPath.row]; 
0

Ваш XML выглядит неправильно. Кажется, что это должно быть так:

<dict> 
<key>Rows</key> 
<array> 
     <dict> 
       <key>MainText</key> 
       <string>A sometext</string> 
       <key>SecondaryText</key> 
       <string>somemoretext</string> 
       <key>PrimaryIcon</key> 
       <string>firsticon.png</string> 
       <key>SecondaryIcon</key> 
       <string>secondicon.png</string> 
     </dict> 
     <dict> 
       <key>MainText</key> 
       <string>B sometext</string> 
       <key>SecondaryText</key> 
       <string>somemoretext</string> 
       <key>PrimaryIcon</key> 
       <string>firsticon.png</string> 
       <key>SecondaryIcon</key> 
       <string>secondicon.png</string> 
     </dict> 
</array> 
</dict> 

Вы можете создать категории для NSDictionary, что позволит вам сортировать данные. Что-то вроде этого:

@interface NSDictionary (Sorting) 

-(NSComparisonResult)compareRows:(NSDictionary*)row; 

@end 

@implementation NSDictionary (Sorting) 

-(NSComparisonResult)compareRows:(NSDictionary*)row; 
{ 
    NSString *rowMainText = [row objectForKey:@"MainText"]; 
    NSString *selfMainText = [self objectForKey:@"MainText"]; 

    return [selfMaintext localizedCompare:rowMainText]; 
} 
@end 

Затем вы можете выполнить свой вид, как это:

[rows sortUsingSelector:@selector(compareRow:)]; 

Переменная строки должны были бы быть изменяемым, так как-то будет выполняться внутри.

+0

Спасибо. Я исправлял plist, когда вы отправили этот ответ:) ... Я как-то испортил его, копируя его в этот пост. Прежде чем я попытаюсь реализовать это, объединяет ли он отдельные словари в разделы на основе значения для «MainText» или просто сортирует их? Спасибо за помощь, этот меня сошел с ума. Я также экспериментировал с UILocalizedIndexedCollation, чтобы узнать, может ли это сделать. – Jonah

+0

Хорошо, просто уточнить. Вы предлагаете создать новую пару файлов .h и .m для хранения этих методов NSComparisonResult? Или я должен добавить их в свой файл RootViewController? Думаю, я не уверен, что вы подразумеваете под «созданием категории для NSDictionary». Большое спасибо за вашу помощь! – Jonah

+0

Это будет просто сортироваться по «MainText», поэтому теперь я вижу, что это может вам не помочь. Методы NSComparisonResult могут быть помещены в их собственный файл, если хотите, что-то вроде NSDictionry + Sorting.h/m, или вы можете просто объявить их в своем классе контроллера вида, что обычно является тем, что я делаю. –

Смежные вопросы