1

I have an NSArray of objects:

MyObject consists of the following string properties:

Title
Category
Name

There are a total of 9 categories.

I would like to display these categories sectioned in a UITableView.

At the moment my code looks like this, but it's not quite right and I'm unsure of how to handle the individual categories in my

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;` as well.

    for (ArrayOfMyObject *item in myArray) {
      if ([item.Category isEqualToString:@"Category1"]) {
        NSDictionary *dict = [NSDictionary dictionaryWithObjects:item forKey:item.Category];
        [self.itemsArray addObject:dict];
      }

      if ([item.Category isEqualToString:@"Category2"]) {
        NSDictionary *dict = [NSDictionary dictionaryWithObjects:item forKey:item.Category];
        [self.itemsArray addObject:dict];
      }
      ... (etc, for the rest of the Category titles).
    }

I should be getting a total of 9 sections if there's 9 categories, but it looks like I'm actually getting the total count of items (there's like 76). Any help would be greatly appreciated and feel free to request more code if need-be.

I guess I would also need to know how to handle this inside the cellForRowAtIndexPath method.

Would I do something like this?

MyObject *item = (MyObject *)[self.itemsArray objectAtIndex:indexPath.row];
NSMutableDictionary *dictionary = [self.itemsArray objectAtIndex:indexPath.section];
NSArray *categoryArray = [dictionary objectForKey:item.Category];
Vladimir
  • 170,431
  • 36
  • 387
  • 313
gotnull
  • 26,454
  • 22
  • 137
  • 203

1 Answers1

3

I'd start by organising your data source in a different way.

Get a datasource NSArray that contains 9 NSDictionaries representing your categories. Inside each category, you have a couple of keys - one for a corresponding string with the category name and one for a corresponding array of MyObjects that belong to the category:

dataSource [
             item1 {
                     catName = @"CategoryName 1"
                     objects = NSArray of MyObjects for catName1
                   }
             item2 {
                     catName = @"CategoryName 2"
                     objects = NSArray of MyObjects for catName2
                   }
             etc...
           ]

Once you have the data organised this way, your datasource methods for the table view will look like this (conceptually):

numberOfSections can be accessed with [datasource count]

titleForSection can be accessed with [[datasource objectAtIndex:indexPath.section] valueForKey:@"catName"]

numberOfRowsInSection can be accessed with [[[datasource objectAtIndex:indexPath.section] valueForKey:@"objects"] count]

And finally, the MyObject for each row can be accessed with [[[datasource objectAtIndex:indexPath.section] valueForKey:@"objects"] objectAtIndex:indexPath.row] on the cellForRowAtIndexPath: method.

Makes sense? Let me know if you have any questions. Cheers, Rog

[EDIT TO ANSWER YOUR FOLLOW UP QUESTION]

This is based on a few assumptions but you should get the gist of it. For the purpose of testing this, I created a MyObject class that returns an instance with random generated category names.

- (void)createDatasource
{
    NSInteger numberOfObjects = 10;
    NSMutableArray *objects = [NSMutableArray arrayWithCapacity:numberOfObjects];
    NSMutableArray *categories = [NSMutableArray arrayWithCapacity:numberOfObjects];
    for (int i = 0; i < numberOfObjects; i++)
    {
        MyObject *obj = [[MyObject alloc] init];
        [objects addObject:obj];
        [categories addObject:obj.category];
        [obj release];
    }
    NSSet *set = [NSSet setWithArray:categories];
    NSMutableArray *dataSource = [[NSMutableArray alloc] initWithCapacity:[set count]];
    for (NSString *categoryString in set)
    {
        NSMutableDictionary *mainItem = [[NSMutableDictionary alloc] initWithObjectsAndKeys:nil, @"categoryName", nil, @"myObjects", nil];
        NSMutableArray *mainItemMyObjects = [NSMutableArray array];
        [mainItem setValue:categoryString forKey:@"categoryName"];
        for (MyObject *obj in objects)
        {
            if ([obj.category isEqualToString:categoryString])
            {
                [mainItemMyObjects addObject:obj];
            }
        }
        [mainItem setValue:mainItemMyObjects forKey:@"myObjects"];
        [dataSource addObject:mainItem];
        [mainItem release];
    }
    NSLog (@"objects = %@\ncategories = %@\nset = %@\ndatasource = %@", objects, categories, set, dataSource);
    // Use and release your datasource as appropriate
    // You may want to sort your datasource appropriately depending on your needs
}
Rog
  • 18,602
  • 6
  • 76
  • 97
  • Makes sense but can you elaborate on the creation of the dataSource? – gotnull Mar 12 '11 at 13:28
  • 1
    @Fulvio I had a go making a few assumptions - see edited post. There's an alternative which is using a NSFetchedResultsController but the above should achieve a similar outcome provided your data doesn't change all the time (and the table has to be refreshed accordingly). If that's the case have a look at fetched results controller documentation for details. – Rog Mar 12 '11 at 22:53
  • I have a date, which is a property of MyObject. Ideally I would like to be able to sort the data by date descending. So therefore the latest item will be first displayed (therefore obviously making the sections display in a different order every time depending on what the first item/section is). Thank you so much for your current answer, I'm definitely going to use this and accept this as the answer but I'm just wondering whether you could also help me with ordering? Thank you. – gotnull Mar 13 '11 at 00:52
  • 1
    @Fulvio No worries - here's a good reference to help you work out the sorting http://stackoverflow.com/questions/805547/how-to-sort-an-nsmutablearray-with-custom-objects-in-it – Rog Mar 13 '11 at 02:08
  • I saw that reference, tried to implement it in a way which I thought would work, however I'm only able to sort the data within each section. What I'm after is sorting the sections in order with the data - if that makes sense. – gotnull Mar 13 '11 at 02:45