从plist中获取字典数组并根据键的值创建部分的最佳方法

时间:2009-08-12 02:15:53

标签: iphone arrays uitableview dictionary

我有一个plist,其中包含一个包含字典集合的数组。数组中的字典用于创建相当复杂的表视图,每个单元格中包含2个图像和2行文本。我想基于与“MainText”键对应的值的第一个字母在tableview中创建节。

这是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方法中获取正确的行?目前,每个部分只显示从第一个开始的相同单元格。我需要以某种方式在我的数据源中定义有不同的部分。感谢您的帮助,这是一场真正的斗争!

2 个答案:

答案 0 :(得分: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];

答案 1 :(得分: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:)];

变量 rows 需要是可变的,因为排序将在内部执行。