I have an app that basically reads an xml file and displays the results in a UITableView. I am trying to group the list items by "country" (an attribute of the xml file elements) and display them in UITableView Sections.
Currently i read the xml file and store each Element as a custom object in an NSMutableArray. The array has the following structure:
Array: 0 => (title, description, date, country) 1 => (title, description, date, country) 2 => (title, description, date, country) 3 => (title, description, date, country)
I have tried creating another array of unique countries which has allowed me to create the section headers correctly but i am struggling to work out a way to display the correct items beneath each section header.
if(![countryArray containsObject:itemCountry]) //if country not already in array
{
[countryArray addObject:itemCountry]; //Add NSString of country name to array
}
Where itemCountry is the country attribute of each element as i loop through the xml file.
[countryArray count]; //gives me the amount of sections needed
So i guess my question is how do i work out how many rows need to go in each section? How do display the correct array items for each section?
Any help or pointers would be great
Rather than creating an array of custom objects containing your data, you should look at creating a dictionary.
NSMutableDictionary * theDictionary = [NSMutableDictionary dictionary];
// Here `customObjects` is an `NSArray` of your custom objects from the XML
for ( CustomObject * object in customObjects ) {
NSMutableArray * theMutableArray = [theDictionary objectForKey:object.country];
if ( theMutableArray == nil ) {
theMutableArray = [NSMutableArray array];
[theDictionary setObject:theMutableArray forKey:object.country];
}
[theMutableArray addObject:object];
}
/* `sortedCountries` is an instance variable */
self.sortedCountries = [[theDictionary allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
/* Save `theDictionary` in an instance variable */
self.theSource = theDictionary;
Later in numberOfSectionsInTableView
:
- (NSInteger)numberOfSectionsInTableView {
return [self.sortedCountries count];
}
In tableView:numberOfRowsInSection:
:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[self.theSource objectForKey:[self.sortedCountries objectAtIndex:section]] count];
}
In tableView:cellForRowAtIndexPath:
:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
[..]
/* Get the CustomObject for the row */
NSString * countryName = [self.sortedCountries objectAtIndex:indexPath.section];
NSArray * objectsForCountry = [self.theSource objectForKey:countryName];
CustomObject * object = [objectsForCountry objectAtIndex:indexPath.row];
/* Make use of the `object` */
[..]
}
This should take you the whole way.
Side Note
If it weren't to present the data and just get the count of the countries then a better alternative to PengOne's approach is to use an NSCountedSet
.
NSCountedSet * countedSet = [NSCounted set];
for ( NSString * countryName in countryNames ) {
[countedSet addObject:countryName];
}
Now all unique countries are available in [countedSet allObjects]
and count for each country would be [countedSet countForObject:countryName]
.
For the section headers using Deepak's answer just go:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [self.sortedCountries objectAtIndex:section];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With