views:

349

answers:

2

I've got a class of object with a category property (task.category), which is set to an integer value (1, 2, or 3). I'd like to have a grouped table build itself by putting each task into the right section...

How do I get certain cell objects to be drawn in certain sections of a grouped table, based on one of their properties?

Thanks! :)

+2  A: 

There is no way to do that automagically. You still have to implement all necessary methods of UITableViewDataSource. In order for your datasource methods to provide correct data, you should build some suitable data structure first by grouping your tasks by category. The easiest way would be to build a NSDictionary with the category (wrapped in NSNumber) as key and an NSArray of corresponding tasks as value.

To build this dictionary, do something like this (not tested):

NSArray* keys = [NSArray arrayWithObjects:[NSNumber numberWithInteger:1], [NSNumber numberWithInteger:2], [NSNumber numberWithInteger:3], nil];
NSArray* objects = [NSArray arrayWithObjects:[NSMutableArray array], [NSMutableArray array], [NSMutableArray array], nil];
self.dict = [NSDictionary dictionaryWithObjects:objects forKeys:keys];

for(Task* task in tasks) {    // if tasks is your array holding all tasks
    NSNumber* bucket = [NSNumber numberWithInteger:task.category];
    [[dict objectForKey:bucket] addObject:task];
}

The reason why we have to do this NSNumber boilerplate, is that you can't use primitive values (eg. integers) as dictionary keys.

Once you have this dictionary (self.dict in the code below), just implement the necessary UITableViewDataSource methods:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 3;    // supposing you have 3 categories
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSArray* tasks = [self.dict objectForKey:[NSNumber numberWithInteger:(section + 1)]];
    return [tasks count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSArray* tasks = [self.dict objectForKey:[NSNumber numberWithInteger:(indexPath.section + 1)]];
    Task* task = [tasks objectAtIndex:indexPath.row];

    // other stuff usually done here (create cell, set content of cell etc.)
}

Of course, this is just one possible approach, but I hope it helps to get you on the right track.

Daniel Rinser
That sounds great; probably exactly what I need, thanks. Only problem is I can't figure out how to get the right task objects into the right arrays. In pseudocode, I want: `for each task object, add to the Category1 array if task.category == 1`.
Triz
I just updated my answer and added some sample code to build the dictionary. Maybe it's not the nicest way to do this, but it should work.
Daniel Rinser
Ahhh, awesome. Okay. Quick question: `self.dict` doesn't exist yet... Where does that come from?
Triz
I don't know where your data (the tasks) come from, but you should consider to store them in some grouped format, so you don't have to completely re-group them again and again.. Ideally, you should store them in a format directly usable by the table view datasource (eg. dictionary as proposed above; 3 separate arrays etc.)
Daniel Rinser
The tasks get pulled from an sqlite db, and then each field from the database is mapped to a property of the `task` class. I'm only doing that because it's what the sqlite examples I was drawing from used; I'm sure there's a better way to manage this stuff.
Triz
It's supposed to be a property of type NSDictionary*. It would definitely be out of scope of this comment to explain properties in detail. Have a look at http://developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/ObjectiveC/Articles/ocProperties.html and maybe also http://theocacao.com/document.page/510 (or search stack overflow) - believe me, you will have to familiarize yourself with properties anyway sooner or later.. ;-)
Daniel Rinser
Yeah, it appears to be an important thing to figure out. :) I thought I was doing it correctly by adding `@property(nonatomic,retain) NSDictionary *dict;` to the .h file, but that doesn't seem to work. I'll keep plugging away at it -- thanks a ton for your insights.
Triz
Nevermind that last bit; I had forgotten to also add it under the `@interface RootViewController : UITableViewController {` bit. No errors! Now let's see if I can do something useful with all this. :)
Triz
Mr. Rinser, you are a genius. I have complete functionality now! Cheers, mate; I'll probably be back with more questions soon. :D
Triz
A: 

If you want to learn, how to have a sectioned tableView into your applicaiton.

I think you should visit following link.

http://www.iphonesdkarticles.com/2009/01/uitableview-sectioned-table-view.html

After visiting that link, you might understand - how to have a sectioned-tableView - that you needed in your application.

After understanding the tutorial, you may develop your own sectioned table as per your requirements. Best of Luck.

sugar
That is indeed exactly what I want to do, but there's a twist to my situation that is causing the grief here: I don't know *ahead* of time which objects need to go in which arrays. It needs to be checked at runtime -- each object needs to be interrogated to see what its Category is (because these will be changing all the time), and then sorted appropriately.
Triz
sugar