Desmond
Desmond

Reputation: 5011

How to show an index that looks like the iPod music with # for non english songs

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.

enter image description here

would to show something like iPod.

enter image description here

   -(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

Answers (3)

Desmond
Desmond

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

Antonio E.
Antonio E.

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

Christian
Christian

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

Related Questions