Reputation: 37
Hello I have created one of my application in which i have implemented sorting functionality in a table view The sorting method is working fine on iOS 4 and 5 but when I try to test the application on iOS 6, it shows an error in the sorting method on iOS 6 Please help
Method :-
-(void)setupIndexData{
self.arrayOfCharacters =[[NSMutableArray alloc]init];
self.objectForCharacter=[[NSMutableDictionary alloc]init];
NSNumberFormatter *formatter =[[NSNumberFormatter alloc]init];
NSMutableArray *arrayOfNames =[[NSMutableArray alloc]init];
NSString *numbericSection = @"#";
NSString *firstLetter;
for (NSDictionary *item in self.mCompanyarray) {
firstLetter = [[[item valueForKey:@"Company"]description] substringToIndex:1];
// Check if it's NOT a number
if ([formatter numberFromString:firstLetter] == nil) {
/**
* If the letter doesn't exist in the dictionary go ahead and add it the
* dictionary.
*
* ::IMPORTANT::
* You HAVE to removeAllObjects from the arrayOfNames or you will have an N + 1
* problem. Let's say that start with the A's, well once you hit the
* B's then in your table you will the A's and B's for the B's section. Once
* you hit the C's you will all the A's, B's, and C's, etc.
*/
if (![objectForCharacter objectForKey:firstLetter]) {
[arrayOfNames removeAllObjects];
[arrayOfCharacters addObject:firstLetter];
}
[arrayOfNames addObject:item];
/**
* Need to autorelease the copy to preven potential leak. Even though the
* arrayOfNames is released below it still has a retain count of +1
*/
[objectForCharacter setObject:[[arrayOfNames copy] autorelease] forKey:firstLetter];
} else {
if (![objectForCharacter objectForKey:numbericSection]) {
[arrayOfNames removeAllObjects];
[arrayOfCharacters addObject:numbericSection];
}
[arrayOfNames addObject:item];
[objectForCharacter setObject:[[arrayOfNames copy] autorelease] forKey:numbericSection];
}
}
[formatter release];
[arrayOfNames release];
[self.mCompaniesTableView reloadData];
}
Thanks
Upvotes: 0
Views: 1169
Reputation: 306
I'd use UILocalizedIndexedCollation to sort and index your data. That way, your app can support multiple languages etc.
Note: I haven't tested the code below, but the theory is there.
First, create a @property to store the indexed data:
@property (nonatomic, strong) NSDictionary *indexedSections;
Set up your table like this:
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return [[UILocalizedIndexedCollation currentCollation] sectionIndexTitles];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
//we use sectionTitles and not sections
return [[[UILocalizedIndexedCollation currentCollation] sectionTitles] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[self.indexedSections objectForKey:[NSNumber numberWithInteger:section]] count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
BOOL showSection = [[self.indexedSections objectForKey:[NSNumber numberWithInteger:section] count] != 0;
//only show the section title if there are rows in the section
return (showSection) ? [[[UILocalizedIndexedCollation currentCollation] sectionTitles] objectAtIndex:section] : nil;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
id object = [[self.indexedSections objectForKey:[NSNumber numberWithInteger:indexPath.section]] objectAtIndex:indexPath.row];
// configure the cell
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
//sectionForSectionIndexTitleAtIndex: is a bit buggy, but is still useable
return [[UILocalizedIndexedCollation currentCollation] sectionForSectionIndexTitleAtIndex:index];
}
And finally index like this:
- (void) setupIndexData
{
// asynchronously sort
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
{
// create a dictionary to store an array of objects for each section
NSMutableDictionary *tempSections = [NSMutableDictionary dictionary];
// iterate through each dictionaey in the list, and put them into the correct section
for (NSDictionary *item in self.mCompanyarray)
{
// get the index of the section (Assuming the table index is showing A-#)
NSInteger indexName = [[UILocalizedIndexedCollation currentCollation] sectionForObject:[item valueForKey:@"Company"] collationStringSelector:@selector(description)];
NSNumber *keyName = [NSNumber numberWithInteger:indexName];
// if an array doesnt exist for the key, create one
NSMutableArray *arrayName = [tempSections objectForKey:keyName];
if (arrayName == nil)
{
arrayName = [NSMutableArray array];
}
// add the dictionary to the array (add the actual value as we need this object to sort the array later)
[arrayName addObject:[item valueForKey:@"Company"]];
// put the array with new object in, back into the dictionary for the correct key
[tempSections setObject:arrayName forKey:keyName];
}
/* now to do the sorting of each index */
NSMutableDictionary *sortedSections = [NSMutableDictionary dictionary];
// sort each index array (A..Z)
[tempSections enumerateKeysAndObjectsUsingBlock:^(id key, id array, BOOL *stop)
{
// sort the array - again, we need to tell it which selctor to sort each object by
NSArray *sortedArray = [[UILocalizedIndexedCollation currentCollation] sortedArrayFromArray:array collationStringSelector:@selector(description)];
[sortedSections setObject:[NSMutableArray arrayWithArray:sortedArray] forKey:key];
}];
// set the global sectioned dictionary
self.indexedSections = sortedSections;
dispatch_async(dispatch_get_main_queue() ,^{
// reload the table view (on the main thread)
[self.mCompaniesTableView reloadData];
});
});
}
Upvotes: 2