IOS 表视图(UITableVIew)的使用方法(3)名单的索引显示

当数据量特别大时,简单地以role进行分段,对实际查找的效率提升并不大。就像上一节开头所说,开发者可以根据球员名字的首字母进行分段,且分成26段。由于段数较多,可以使用UITableView的索引机制,在界面的右侧展示一条垂直的字母列表,使用户可以快速地在段与段之间进行切换。

新建一个继承自SimpleTableViewController的子类名为IndexedTableViewController,头文件声明如下:

1 #import "HBSimpleTableViewController.h"

2 #import "ChineseString.h"

3 #import "pinyin.h"

4 

5 @interface HBIndexedTableViewController : HBSimpleTableViewController

6 {

7     //即表示每段的段名,也表示索引表的内容

8     NSArray *_indexTitles;

9 }

并且在SimpleTableViewController的数据源的基础上,对其进行改善优化,数据源将会得到重新制作,代码如下:

  1 -(void)initData

  2 {

  3     [super initData];

  4     

  5     //将26个字母放进_indexTitles中

  6     //表示段名,也表示索引表的内容

  7     NSMutableArray *arrTmp=[NSMutableArray arrayWithCapacity:0];

  8     for (char c='A';c<='Z';c++) {

  9         [arrTmp addObject:[NSString stringWithFormat:@"%c",c]];

 10     }

 11     if (_indexTitles) {

 12         _indexTitles=nil;

 13     }

 14     

 15     _indexTitles = [[NSArray alloc]initWithArray:arrTmp];

 16     

 17     //中文排序

 18     //step1:获取要排序的数组

 19     NSMutableArray *shouldSortArray=[NSMutableArray arrayWithArray:self.datasource];

 20     

 21     //step2:获取字符串中文字的拼音首字母并与字符串共同存放

 22     NSMutableArray *chineseStringsArray=[NSMutableArray array];

 23     for (int i=0; i<[shouldSortArray count]; i++) {

 24         ChineseString *chineseString=[[ChineseString alloc]init];

 25         

 26         HBPlayerInfo *onePlaer=[shouldSortArray objectAtIndex:i];

 27         

 28         chineseString.string=[NSString stringWithString:onePlaer.name];

 29         

 30         if(chineseString.string == nil)

 31         {

 32             chineseString.string = @"";

 33         }

 34         

 35         if(![chineseString.string isEqualToString:@""])

 36         {

 37             NSString *pinYinResult=[NSString string];

 38             for (int j=0; j<chineseString.string.length; j++) {

 39                 NSString *singlePinyinLetter=[[NSString stringWithFormat:@"%c",pinyinFirstLetter([chineseString.string characterAtIndex:j])]uppercaseString];

 40                 

 41                 pinYinResult=[pinYinResult stringByAppendingString:singlePinyinLetter];

 42             }

 43             chineseString.pinYin=pinYinResult;

 44         }

 45         else

 46         {

 47             chineseString.pinYin=@"";

 48         }

 49         [chineseStringsArray addObject:chineseString];

 50     }

 51     

 52     //step2的输出

 53     NSLog(@"\n\n\n转换为拼音首字母后的NSString数组");

 54     for (int i=0; i<[chineseStringsArray count]; i++) {

 55          ChineseString *chineseString=[chineseStringsArray objectAtIndex:i];

 56        NSLog(@"原String:%@----拼音首字母String:%@",chineseString.string,chineseString.pinYin);

 57     }

 58     

 59     //step3:按照拼音首字母对这些string进行排序

 60     NSArray *sortDescriptors=[NSArray arrayWithObjects:[NSSortDescriptor sortDescriptorWithKey:@"pinYin" ascending:YES], nil];

 61     

 62     [chineseStringsArray sortUsingDescriptors:sortDescriptors];

 63     

 64     //step3的输出

 65     NSLog(@"\n\n\n按照拼音首字母后的NSString数组");

 66     for(int i=0;i<[chineseStringsArray count];i++){

 67         ChineseString *chineseString=[chineseStringsArray objectAtIndex:i];

 68         NSLog(@"原String:%@----拼音首字母String:%@",chineseString.string,chineseString.pinYin);

 69     }

 70     

 71     //step4:如果有需要,再把排序好的内容从ChineseString类中提取出来

 72     NSMutableArray *result=[NSMutableArray array];

 73     NSMutableArray *pinYinResult=[NSMutableArray array];

 74     for(int i=0;i<[chineseStringsArray count];i++){

 75         [result addObject:((ChineseString*)[chineseStringsArray objectAtIndex:i]).string];

 76         [pinYinResult addObject:((ChineseString *)[chineseStringsArray objectAtIndex:i]).pinYin];

 77     }

 78     //Step4输出

 79     NSLog(@"\n\n\n最终结果:");

 80     for(int i=0;i<[result count];i++){

 81         NSLog(@"%@",[result objectAtIndex:i]);

 82     }

 83     

 84     

 85     //得到名字排好序的数据源后,需要将这些球员对象根据名字的首字母,进行分段

 86     NSMutableArray *arrAll = [NSMutableArray arrayWithCapacity:0];

 87     

 88     //遍历26个字母

 89     for(NSString *aIndexTitle in _indexTitles)

 90     {

 91         arrTmp=[[NSMutableArray alloc]initWithCapacity:0];

 92         

 93         //遍历球员对象,找到那些名字是当前字母的球员,加到arrTmp中去

 94         for (ChineseString *oneChineseString in chineseStringsArray) {

 95             NSString *pinYin=oneChineseString.pinYin;

 96             NSString *firstPinYin=[pinYin substringToIndex:1];

 97             

 98             //不区分大小写比较

 99             if([[firstPinYin lowercaseString] hasPrefix:[aIndexTitle lowercaseString]])

100             {

101                 [arrTmp addObject:oneChineseString];

102             }

103         }

104         [arrAll addObject:arrTmp];

105     }

106     //重置数据源,进行赋值

107     

108     if(_datasource)

109     {

110         _datasource=nil;

111     }

112     _datasource = [[NSArray alloc] initWithArray:arrAll];

113 }

数据源操作完,对于UITableView的数据源回调函数,需要为索引机制定做一套

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

{

    return _indexTitles.count;

}



//每段几行

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

{

    if(!self.datasource)

    {

        return 0;

    }

    

    NSArray *arrSectionPlayer=[self.datasource objectAtIndex:section];

    return arrSectionPlayer.count;

}



//索引表内容

-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView

{

    return _indexTitles;

}



//索引表与段之间的关联

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

{

    //告诉我们一个段名和该段的序号

    //我们需要返回一个对于索引表数组内容的序号

    NSInteger count=0;

    for (NSString *aAlpha in _indexTitles) {

        if ([aAlpha isEqualToString:title]) {

            return count;

        }

        count++;

    }

    return 0;

}



-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

    static NSString *CellIdentifier = @"IndexTableViewCellId";

    UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if(cell == nil)

    {

        cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

    }

    

    //数据源有两层,需要注意获取特定球员对象的方法

    ChineseString *chineseString=nil;

    NSArray *arrSectionPlayer = [self.datasource objectAtIndex:indexPath.section];

    if(arrSectionPlayer && arrSectionPlayer.count>indexPath.row)

    {

        chineseString=[arrSectionPlayer objectAtIndex:indexPath.row];

    }

    if(chineseString)

    {

        cell.textLabel.text=chineseString.string;

    }

    return cell;

}

另外,段名并非一定需要实现其数据源回调函数,使用代理回调函数也能够对段名进行配置,代码如下:

#pragma mark-

#pragma mark TableView delegate

//段名高22px高

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section

{

    return 22.0f;

}



-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

{

    //使用UILabel来显示段名

    NSString *strHeaderTitle = @"";

    UILabel *labHeaderView = [[UILabel alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 22.0f)];

    

    if(_indexTitles && section < _indexTitles.count)

    {

        strHeaderTitle = [_indexTitles objectAtIndex:section];

    }

    labHeaderView.text = [NSString stringWithFormat:@"  %@",strHeaderTitle];

    labHeaderView.textColor = [UIColor whiteColor];

    labHeaderView.shadowColor = [UIColor grayColor];

    labHeaderView.shadowOffset = CGSizeMake(1.0f, 1.0f);

    labHeaderView.font =[UIFont fontWithName:@"Helvetica" size:16.0f];

    labHeaderView.backgroundColor=[UIColor colorWithRed:200.0f/255.0f green:200.0f/255.0f blue:200.0f/255.0f alpha:1.0f];

    

    return labHeaderView;

}

运行程序,得到如图14.8所示的结果。IOS 表视图(UITableVIew)的使用方法(3)名单的索引显示

你可能感兴趣的:(UITableView)