Seb OH
Seb OH

Reputation: 835

Ordering objects under sections

Below is a screenshot of a UITableView that I want to order into by month. Currently their ordered by the first letter of the sub-heading in alphabetical order, what code should I use to make the events ordered into months? (By the way I have worked out how to order the sections)

Image to be ordered

Any help appreciated,

Seb

Upvotes: 0

Views: 109

Answers (1)

Bogatyr
Bogatyr

Reputation: 19343

The best solution depends on what your data model looks like. Probably the simplest and most efficient, assuming your data model does not change very frequently, is just to have a routine that sorts each section's data in the order you want (based on each item's date). Create a list of pointers (or indices, again depending on your data structure's details), then all you have to do is look up the row index in the section's sorted index structure and display that element's data in your cellForRowAtIndexPath.

To optimize, you can keep a boolean "sorted" field in your data structure that is set to false whenever the data mutates in the table, then only sort on demand in the cellForRowAtIndexPath and set "sorted" to true.

EDIT: request for more step-by-step detailed description

OK, here's a bit more detail on how I'd go about it, assuming each of your sections is stored unsorted in a sortable container like NSMutableArray. Again the best solution depends on the details of your app like how frequently the section entries update and how you organize your data, and is there an upper bound on the number of entries in a section, etc. This is slightly different from my original suggestion in that the section's data container is directly sorted, and doesn't use an external ordering index.

Add a NSMutableSet sortedSections member somewhere convenient, close to your data model (inside its class would be best if you define it in a class)

// a section number is sorted if and only if its number is in the set
NSMutableSet *sortedSections;

When entries in sections are changed, added, or deleted, mark that section as unsorted by removing its number from the set

// just added, deleted, or changed a section entry entry 
unsigned int sectionNum;    // this section changed
...
NSNumber *nsNum = [NSNumber numberWithUnsignedInt:sectionNum];
[obj.sortedSections removeObject:nsNum];

In your cellForRowAtIndexPath (this may not be the most optimal place for this check, but it is a fast check and is the easiest location to get the sorting working), check if the section is sorted.

unsigned int sectionNum = [indexPath section];
NSNumber *nsNum = [NSNumber numberWithUnsignedInt:sectionNum];
if ( [obj.sortedSections containsObject:nsNum] )
    // already sorted, nothing to do
else
{
    // section needs to be resorted and reloaded
    [mySectionData sortUsingFunction:compareSectionEntriesByDate context:nil];
    // mark the section as sorted now
    [obj.sortedSections addObject:nsNum];
    [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationNone];
}

Here is an example sorting function, assuming your entry structures are of type NSDictionary and that you store the dates as NSDate objects with the key constant kEntryNSDate (which you would define yourself)

// sort compare function for two section entries based on date
//

static int compareSectionEntriesByDate( id e1, id e2, void *context)
{
    NSDictionary *eDict1 = (NSDictionary *) e1;
    NSDictionary *eDict2 = (NSDictionary *) e2;
    NSDate *date1 = [eDict1 objectForKey:kEntryNSDate];
    NSDate *date2 = [eDict2 objectForKey:kEntryNSDate];

    int rv = [date1 compare:date2];
    return rv;
}

That should be enough detail to get you going, good luck!

Upvotes: 1

Related Questions