views:

494

answers:

1

I am a beginning iPhone SDK programmer. I built a simple practice application I am trying to use to learn more about table views. It's an app that loads football teams from a plist and displays them in a table view with their stadium name and logo. Tapping the team goes to a detail view for that team.

I am trying to understand how to add sections to this, so that I might have a couple of teams in one section and others in another section, etc.

I would assume I need to both re-structure my plist and change the code to read arrays from the different levels of the plist?

To begin, I had a plist with the root array consisting of 3 dictionaries, one for each team. Each dictionary had 3 keys, "name" "stadium" and "logo". This works fine. I am loading it via:

NSString *path = [[NSBundle mainBundle] pathForResource:@"teams" ofType:@"plist"];
teams = [[NSMutableArray alloc] initWithContentsOfFile:path];

and then

// Configure the cell.
NSDictionary *team = [teams objectAtIndex:indexPath.row];
cell.textLabel.text = [team objectForKey:@"name"];
NSString *imgPath = [team valueForKey:@"logo"]; 
cell.imageView.image = [UIImage imageNamed:imgPath];
cell.detailTextLabel.text =[team objectForKey:@"stadium"];
return cell;

No problem. But now I wanted the sections, so I changed my plist to:

<array>
<dict>
    <key>teams 1</key>
    <array>
        <dict>
            <key>name</key>
            <string>Packers</string>
            <key>stadium</key>
            <string>Lambeau Field</string>
            <key>logo</key>
            <string>packers.jpg</string>
        </dict>
        <dict>
            <key>name</key>
            <string>Jets</string>
            <key>stadium</key>
            <string>Giants Stadium</string>
            <key>logo</key>
            <string>jets_logo.jpg</string>
        </dict>
    </array>
</dict>
<dict>
    <key>teams 2</key>
    <array>
        <dict>
            <key>name</key>
            <string>Cincinnati Bengals</string>
            <key>stadium</key>
            <string>Paul Brown Stadium</string>
            <key>logo</key>
            <string>bengals.jpg</string>
        </dict>
    </array>
</dict>

And I am unsure how to modify the viewDidLoad to assign the sections to one NSArray and the teams "level" to another array.

A: 

First of all, you need to use arrays for the top two levels of your data structure. Dictionaries are unordered so that makes it hard to use them as the data source for a table's format. It's fine to use them for the data for each record displayed in an individual cell. To use the dictionaries as table format data, you have to store their keys to an array so that every key has a specific numerical index that the table can use to find the key.

You will need something like the following in your UITabelViewDataSource class:

@property(nonatomic, retain)  NSArray *sectionNames;
...
NSArray *sectionNames=[teams allKeys];

In your UITabelViewDataSource class you would need these methods:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return [self.sectionNames count];
}

This returns the number of sections in the table which in your case represents the number of objects in your top level dictionary.

- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section{
    return [[teams valueForKey:[self.sectionNames objectAtIndex:section] count];
}

This returns the number of rows within each section which in your case means the number of objects in each second level dictionary returned for the key stored in each sectionName element.

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
       return [self.sectionNames objectAtIndex:section];
}

This returns the name that will be displayed for each section header which in your case is the key for each first level dictionary value.

Unless you have a specific need to reference the sections by key, you should think about storing everything except the team data in arrays instead of dictionaries. It will make you tables easier to implement.

TechZen