Reputation: 5011
I would like to show an index bar on my tableview with all my songs sorted by alphabetical order and those foreign language songs and numerical in # just like how the iPod music in iOS. I read the first character of all my song array object exclude duplicates and append it as the index. How can i filter foreign / non alphabet and numbers ?
this is how it looks like, ugly.
would to show something like iPod.
-(NSMutableArray *)updateSongSectionIndexWithArray:(NSArray*)songArray andSelector:(SEL)selector
{
NSArray *indexedArray = [self partitionObjects:songArray collationStringSelector:selector];
return [[NSMutableArray alloc]initWithArray:indexedArray];
}
-(NSArray *)partitionObjects:(NSArray *)array collationStringSelector:(SEL)selector
{
self.collation = [UILocalizedIndexedCollation currentCollation];
NSInteger sectionCount = [[self.collation sectionTitles] count];//section count is take from sectionTitles and not sectionIndexTitles
NSMutableArray *unsortedSections = [NSMutableArray arrayWithCapacity:sectionCount];
//create an array to hold the data for each section
for(int i = 0; i < sectionCount; i++)
{
[unsortedSections addObject:[NSMutableArray array]];
}
if ([self.catString isEqualToString:ARTISTS])
{
//put each object into a section
for (id object in array)
{
if (!object)
{
continue;
}
NSInteger index = [self.collation sectionForObject:object collationStringSelector:selector];
[[unsortedSections objectAtIndex:index] addObject:object];
}
}
else
{
for (id object in array)
{
NSInteger index = [self.collation sectionForObject:object collationStringSelector:selector];
[[unsortedSections objectAtIndex:index] addObject:object];
}
}
NSMutableArray *sections = [NSMutableArray arrayWithCapacity:sectionCount];
//sort each section
for (NSMutableArray *section in unsortedSections)
{
[sections addObject:[self.collation sortedArrayFromArray:section collationStringSelector:selector]];
}
return sections;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [[[UILocalizedIndexedCollation currentCollation] sectionTitles] count];
}
Upvotes: 3
Views: 435
Reputation: 5011
I ended up getting this my index to work by this
-(NSArray *)partitionObjects:(NSArray *)array collationStringSelector:(SEL)selector
{
self.collation = [UILocalizedIndexedCollation currentCollation];
NSInteger sectionCount = [[self.collation sectionTitles] count];//section count is take from sectionTitles and not sectionIndexTitles
NSMutableArray *unsortedSections = [NSMutableArray arrayWithCapacity:sectionCount];
//create an array to hold the data for each section
for(int i = 0; i < sectionCount; i++)
{
[unsortedSections addObject:[NSMutableArray array]];
}
if ([self.catString isEqualToString:ARTISTS])
{
//put each object into a section
for (id object in array)
{
if (!object)
{
continue;
}
NSInteger index = [self.collation sectionForObject:object collationStringSelector:selector];
[[unsortedSections objectAtIndex:index] addObject:object];
}
}
else
{
NSInteger index;
for (id object in array)
{
Song *songItem = object;
NSString* charIndex;
if([songItem.songName length]<=2)
{
charIndex = [songItem.songName substringToIndex:1];
}
else if([songItem.songName length]<=3)
{
charIndex = [songItem.songName substringToIndex:2];
}
else if([songItem.songName length]<=4)
{
charIndex = [songItem.songName substringToIndex:3];
}
else if([songItem.songName length]>=5)
{
charIndex = [songItem.songName substringToIndex:4];
}
NSRegularExpression *regex = [[NSRegularExpression alloc]
initWithPattern:@"[a-zA-Z]" options:0 error:NULL];
NSUInteger matches = [regex numberOfMatchesInString:charIndex options:0
range:NSMakeRange(0, [charIndex length])];
if (matches >=2)
{
NSLog(@"matches %i",matches);
index = [self.collation sectionForObject:object collationStringSelector:selector];
[[unsortedSections objectAtIndex:index] addObject:object];
}
else
{
index = 26;
[[unsortedSections objectAtIndex:index] addObject:object];
}
NSLog(@"songItem %@ is in index %i",songItem.songName, index);
}
}
NSMutableArray *sections = [NSMutableArray arrayWithCapacity:sectionCount];
//sort each section
for (NSMutableArray *section in unsortedSections)
{
[sections addObject:[self.collation sortedArrayFromArray:section collationStringSelector:selector]];
}
return sections;
}
Upvotes: 1
Reputation: 4391
I did a similar thing for one of my apps. To split titles I used this code:
NSString* alphabet = @"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
NSArray* indexes = [alphabet componentsSeparatedByString:@""];
for (NSString* title in self.titles) {
char c = [[title uppercaseString] characterAtIndex:0];
NSString* index = [NSString stringWithFormat:@"%c",c];
if ([alphabet rangeOfString:index].location == NSNotFound) {
//The title does not start with a valid letter
index = @"#";
}
NSMutableArray* sectionObjects = [self.sections objectForKey:index];
if (!sectionObjects) {
sectionObjects = [[NSMutableArray alloc] init];
[self.sections setObject:sectionObjects forKey:index];
}
[sectionObjects addObject:title];
}
Obviously this code is still missing the sort part since it's trivial.
Upvotes: 2
Reputation: 4641
I did a similar solution for a contacts application. I start by defining the alphabet myself, then you can add to each section the items that fit (case insensitive compare for the letters, Characterset for the numbers). After the list is filled, you can remove (or hide) the sections which have no entry.
Upvotes: 2