WunDaii
WunDaii

Reputation: 2312

tableView Index # for Numbers?

I have an indexed tableView that displays a list of songs from the user's iPod library. But the sections start with 1, 2, etc., because I have songs that start with numbers. How do I group all songs that start with a number into a section '#' in my index?

Right now this is my app (left) compared to what I'd like it to be (right, Music.app). I've highlighted where the # should go (at the end of my index):

Examples

This is my code so far in my viewDidLoad:

songsQuery = [MPMediaQuery songsQuery];
songs = [songsQuery items];

NSMutableDictionary *songsInitials;

songsInitials = [[NSMutableDictionary alloc]init];
self.alphabetArray = [[NSMutableArray alloc] init];

for (int i=0; i< songs.count; i++)
{
    NSString *firstletter=[[[songs objectAtIndex:i] valueForProperty:MPMediaItemPropertyTitle] substringToIndex:1];

    if (songsInitials[firstletter] == nil) {
            songsInitials[firstletter] = [[NSMutableArray alloc] init];
            [self.alphabetArray addObject:firstletter];
    }  

    [songsInitials[firstletter] addObject:songs[i]];

}

[self.alphabetArray sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];   //sorting array in ascending array

self.songsInitials = songsInitials;

....and my tableView data source:

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return _alphabetArray.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

    return [_songsInitials[_alphabetArray[section]] count];
}

-(NSString *)titleForRow:(NSIndexPath *)indexpath{

    NSString *firstLetter = _alphabetArray[indexpath.section];
    MPMediaItem *myItem = [_songsInitials[firstLetter] objectAtIndex:indexpath.row];

    return [myItem valueForProperty:MPMediaItemPropertyTitle];
}

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{
    return self.alphabetArray;
}

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index{

    NSIndexPath *indexpath;

    for (int i=0; i < self.alphabetArray.count; i++)
    {
        NSString *titleToSearch=[self.alphabetArray objectAtIndex:i];  //getting sectiontitle from array
        if ([title isEqualToString:titleToSearch])  // checking if title from tableview and sectiontitle are same
        {
            indexpath=[NSIndexPath indexPathForRow:0 inSection:i];
            // scrolling the tableview to required section
            [self.songsTable scrollToRowAtIndexPath:indexpath atScrollPosition:UITableViewScrollPositionTop animated:YES];
            break;
        }
    }
    return indexpath.section;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    cell.textLabel.text= [self titleForRow:indexPath];  //getting cell content

    return cell;
}

This is what I've tried so far, adjusting the for loop in viewDidLoad:

for (int i=0; i< songs.count; i++)
    {
        NSString *firstletter=[[[songs objectAtIndex:i] valueForProperty:MPMediaItemPropertyTitle] substringToIndex:1];
        if (songsInitials[firstletter] == nil) {
            NSString *songsInitialsFirstLetter = songsInitials[firstletter];

            if ([self stringIsNumeric:songsInitialsFirstLetter]){
                songsInitials[firstletter] = [[NSMutableArray alloc] init];
                [self.alphabetArray addObject:[NSString stringWithFormat:@"#"]];
                NSLog(@"There are numbers!");
            }
            else if (![self stringIsNumeric:songsInitialsFirstLetter]){
                songsInitials[firstletter] = [[NSMutableArray alloc] init];
                [self.alphabetArray addObject:firstletter];
            }

        }

        [songsInitials[firstletter] addObject:songs[i]];

    }

-(BOOL) stringIsNumeric:(NSString *) str {
    NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
    NSNumber *number = [formatter numberFromString:str];
    return !!number; // If the string is not numeric, number will be nil
}

...but it didn't work. I've searched around but I can't find any other questions that ask this, am I missing something obvious here? Any help would be much appreciated! :)

Upvotes: 1

Views: 306

Answers (1)

user3802077
user3802077

Reputation: 849

Did not test but changing first letter before looking in the arrays would give better result. After the sort, not sure where the symbol (#) will end tough, you may have to manual push it to the end.

for (int i=0; i< songs.count; i++)
{
    NSString *firstletter=[[[songs objectAtIndex:i] valueForProperty:MPMediaItemPropertyTitle] substringToIndex:1];
    NSScanner *ns = [NSScanner scannerWithString:firstletter];
    if ( [ns scanInt:NULL] )
    {
         firstLetter = @"#";
    }

    if (songsInitials[firstletter] == nil) {
        songsInitials[firstletter] = [[NSMutableArray alloc] init];
        [self.alphabetArray addObject:firstletter];
    }  

    [songsInitials[firstletter] addObject:songs[i]];

}

Upvotes: 1

Related Questions