【问题标题】:Create index for UITableView from an NSArray从 NSArray 为 UITableView 创建索引
【发布时间】:2011-08-23 09:23:09
【问题描述】:

我读过创建索引(uitableview 旁边的 a-z)的最佳方法是设置一个 nsdictionaries 数组,其中每个字典对应一个部分,并且 rowValue 键包含一个数组行。

NSDictionary
    headerTitle => ‘A’
    rowValues => {”Aardvark”, “Ape”, “Aquaman”}
NSDictionary
    headerTitle => ‘B’
    rowValues => {”Bat”, “Boot”, “Bubbles”} etc

但是如何从所有行标题的数组中创建它 - {”Aardvark”、“Ape”、“Aquaman”、“Bat”、“Boot”、“Bubbles”、“Cat”、“Cabbage”等等} ...?

【问题讨论】:

    标签: objective-c ios uitableview nsarray nsdictionary


    【解决方案1】:

    我最近有一个类似的目标,这就是我解决它的方法。与 Robin 的解决方案相比,它的优势在于它会根据数组的内容动态创建索引标题数组,并且不会包含空白部分的索引(而且它更简洁一些)。

    我创建了一个NSMutableDictionary 类别,它接受一个数据数组作为参数并返回一个NSMutableDictionary(我们称之为indexDictionary,它应该是一个实例变量):

    // if your data is static, you can call this in `viewDidLoad`
    indexDictionary = [NSMutableDictionary createDictionaryForSectionIndex:arrayOfStrings];
    

    分类方法:

    @implementation NSMutableDictionary (DictionaryForSectionIndex)
    
    +(NSMutableDictionary *)createDictionaryForSectionIndex:(NSArray *)array
    {
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        for (char firstChar = 'a'; firstChar <= 'z'; firstChar++)
        {
            //NSPredicates are fast
            NSString *firstCharacter = [NSString stringWithFormat:@"%c", firstChar];
            NSArray *content = [array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF beginswith[cd] %@", firstCharacter]];
            NSMutableArray *mutableContent = [NSMutableArray arrayWithArray:content];
    
            if ([mutableContent count] > 0)
            {
                NSString *key = [firstCharacter uppercaseString];
                [dict setObject:mutableContent forKey:key];
                NSLog(@"%@: %u", key, [mutableContent count]);
            }
        }
    
        return dict;
    }
    
    @end
    
    /*
    
    **Input:** 
    {"Aardvark", "Cabbage", "Boot", "Eggs", "Ape", "Aquaman", "Elephant", "Cat", "Bat", "Bubbles"}
    
    **Output:**
    NSMutableDictionary
        key => 'A'
        object => {"Aardvark", "Ape", "Aquaman"}
    
        key => 'B'
        object => {"Bat", "Boot", "Bubbles"}
    
        key => 'C'
        object => {"Cat", "Cabbage"}
    
        key => 'E'
        object => {"Elephant", "Eggs"}
    
    */
    

    然后我创建一个NSArray 实例变量来排序和存储来自indexDictionary 的所有键:

    // this line should follow the creation of `indexDictionary`
    
    sortedKeys = [[indexDictionary allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
    
    // Output, in this case, is {'A', 'B', 'C', 'E'}
    

    您现在拥有为表设置索引所需的一切。实现以下方法(如果有些东西不能自我解释,请告诉我):

    //this code assumes `sortedKeys` is not empty
    
    #pragma mark - UITableViewDataSource
    
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        return ([sortedKeys count]);
    }
    
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        NSString *key = [sortedKeys objectAtIndex:section];
        return [[indexDictionary valueForKey:key] count];
    }
    
    
    -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
    {
        return ([sortedKeys objectAtIndex:section]);
    }
    
    
    -(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
    {
        return sortedKeys;
    }
    
    
    -(NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
    {
        return index;
    }
    
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        // preceding code...
    
        NSString *key = [sortedKeys objectAtIndex:indexPath.section];
        NSArray *array = [indexDictionary objectForKey:key];
        NSString *yourString = [array objectAtIndex:indexPath.row];
    
        cell.textLabel.text = yourString;
    
        // following code...
    }
    

    结果是一个带有索引的表,该索引会跳过没有关联数据的字母。

    【讨论】:

    • 这是一个非常棒的答案。谢谢。
    • 如果你有一个字典数组而不是一个字符串数组,你唯一需要做的不同就是将你的谓词字符串更新为name beginswith[cd] %@而不是SELF beginswith[cd] %@。这将按每个字典的名称字段对您的字典数组进行排序。
    【解决方案2】:
    #pragma mark -
    #pragma mark View lifecycle
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        NSMutableArray *temp = [[NSMutableArray alloc] init];
        NSMutableArray *temp2 = [[NSMutableArray alloc] init];
        for(int i = 0; i < tableListArray.count; i++)
        {
            NSString *string = [tableListArray objectAtIndex:i];
            NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
            [dict setObject:string forKey:@"Name"];
            [dict setObject:[NSNumber numberWithInt:i] forKey:@"ID"];
            NSString *firstString = [string substringToIndex:1];
            if([temp2 containsObject:firstString] == NO || temp2.count == 0)
            {
                if(temp2.count != 0)
                {
                    [temp addObject:temp2];
                    [temp2 release];
                    temp2 = [[NSMutableArray alloc] init];
                }
                [temp2 addObject:firstString];
            }
            [temp2 addObject:dict];
            [dict release];
        }
        [temp addObject:temp2];
        detailListArray = [[NSArray alloc] initWithArray:temp];
        [temp release];
        [temp2 release];
    }
    
    #pragma mark -
    #pragma mark Table view data source
    - (NSInteger)tableView:(UITableView *)tableView 
    sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
    {
        int i = 0;
        for(NSArray *array in detailListArray)
        {
            NSString *string = [array objectAtIndex:0];
            if([string compare:title] == NSOrderedSame)
                break;
            i++;
        }
        return i;
    }
    
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        return detailListArray.count;
    }
    
    - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
    {
        NSArray *array = [detailListArray objectAtIndex:section];
        return [array objectAtIndex:0];
    }
    
    - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView 
    {
        NSMutableArray *titleArray = [NSMutableArray array];
        [titleArray addObject:@"A"];
        [titleArray addObject:@"B"];
        [titleArray addObject:@"C"];
        [titleArray addObject:@"D"];
        [titleArray addObject:@"E"];
        [titleArray addObject:@"F"];
        [titleArray addObject:@"G"];
        [titleArray addObject:@"H"];
        [titleArray addObject:@"I"];
        [titleArray addObject:@"J"];
        [titleArray addObject:@"K"];
        [titleArray addObject:@"L"];
        [titleArray addObject:@"M"];
        [titleArray addObject:@"N"];
        [titleArray addObject:@"O"];
        [titleArray addObject:@"P"];
        [titleArray addObject:@"Q"];
        [titleArray addObject:@"R"];
        [titleArray addObject:@"S"];
        [titleArray addObject:@"T"];
        [titleArray addObject:@"U"];
        [titleArray addObject:@"V"];
        [titleArray addObject:@"W"];
        [titleArray addObject:@"X"];
        [titleArray addObject:@"Y"];
        [titleArray addObject:@"Z"];
        return titleArray;
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        NSArray *array = [detailListArray objectAtIndex:section];
        return (array.count - 1);
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                                        reuseIdentifier:@"CELL"] autorelease];
        NSArray *array = [detailListArray objectAtIndex:indexPath.section];
        NSDictionary *dict = [array objectAtIndex:indexPath.row + 1];
        cell.textLabel.text = [dict objectForKey:@"Name"];
        return cell;
    }
    
    #pragma mark -
    #pragma mark Table view delegate
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSArray *array = [detailListArray objectAtIndex:indexPath.section];
        NSDictionary *dict = [array objectAtIndex:indexPath.row + 1];
        int entryID = [[dict objectForKey:@"ID"] intValue];
         // Do what ever you want to do with the selected row here....
    }
    

    这是我在最近的一个项目中使用的代码。

    【讨论】:

      【解决方案3】:

      我正在做一个项目,我需要针对同一问题的动态解决方案,所以我想出了这个解决方案,它只返回包含可用部分的字典。希望对某人有所帮助。

      -(NSMutableDictionary *)getSortedDataWithArray:(NSArray *)dataArray{
        NSMutableDictionary *allDataDictionary = [[NSMutableDictionary alloc]init];
      
        for(int i = 0 ; i< dataArray.count ;i++){
      
          NSString *currentStr = [[[dataArray objectAtIndex:i] substringToIndex:1] uppercaseString];
          NSArray *allKeysArray = allDataDictionary.allKeys;
      
          if([allKeysArray containsObject:currentStr]){
              NSMutableArray *currentArray = [[NSMutableArray alloc] initWithArray:[allDataDictionary valueForKey:currentStr]];
              [currentArray addObject:[dataArray objectAtIndex:i]];
              NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF beginswith[c] %@" ,currentStr];
              NSArray *finalArray = [currentArray filteredArrayUsingPredicate:predicate];
              [allDataDictionary setValue:finalArray forKey:currentStr];
          }
          else{
              NSMutableArray *finalArray = [[NSMutableArray alloc] initWithObjects:[dataArray objectAtIndex:i], nil];
      
              [allDataDictionary setValue:finalArray forKey:currentStr];
          }
        }
       return allDataDictionary;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-20
        • 2015-04-13
        • 1970-01-01
        • 1970-01-01
        • 2016-01-10
        相关资源
        最近更新 更多