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

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

 #import "HBSimpleTableViewController.h"
#import "ChineseString.h"
#import "pinyin.h" @interface HBIndexedTableViewController : HBSimpleTableViewController
{
//即表示每段的段名,也表示索引表的内容
NSArray *_indexTitles;
}

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

 -(void)initData
{
[super initData]; //将26个字母放进_indexTitles中
//表示段名,也表示索引表的内容
NSMutableArray *arrTmp=[NSMutableArray arrayWithCapacity:];
for (char c='A';c<='Z';c++) {
[arrTmp addObject:[NSString stringWithFormat:@"%c",c]];
}
if (_indexTitles) {
_indexTitles=nil;
} _indexTitles = [[NSArray alloc]initWithArray:arrTmp]; //中文排序
//step1:获取要排序的数组
NSMutableArray *shouldSortArray=[NSMutableArray arrayWithArray:self.datasource]; //step2:获取字符串中文字的拼音首字母并与字符串共同存放
NSMutableArray *chineseStringsArray=[NSMutableArray array];
for (int i=; i<[shouldSortArray count]; i++) {
ChineseString *chineseString=[[ChineseString alloc]init]; HBPlayerInfo *onePlaer=[shouldSortArray objectAtIndex:i]; chineseString.string=[NSString stringWithString:onePlaer.name]; if(chineseString.string == nil)
{
chineseString.string = @"";
} if(![chineseString.string isEqualToString:@""])
{
NSString *pinYinResult=[NSString string];
for (int j=; j<chineseString.string.length; j++) {
NSString *singlePinyinLetter=[[NSString stringWithFormat:@"%c",pinyinFirstLetter([chineseString.string characterAtIndex:j])]uppercaseString]; pinYinResult=[pinYinResult stringByAppendingString:singlePinyinLetter];
}
chineseString.pinYin=pinYinResult;
}
else
{
chineseString.pinYin=@"";
}
[chineseStringsArray addObject:chineseString];
} //step2的输出
NSLog(@"\n\n\n转换为拼音首字母后的NSString数组");
for (int i=; i<[chineseStringsArray count]; i++) {
ChineseString *chineseString=[chineseStringsArray objectAtIndex:i];
NSLog(@"原String:%@----拼音首字母String:%@",chineseString.string,chineseString.pinYin);
} //step3:按照拼音首字母对这些string进行排序
NSArray *sortDescriptors=[NSArray arrayWithObjects:[NSSortDescriptor sortDescriptorWithKey:@"pinYin" ascending:YES], nil]; [chineseStringsArray sortUsingDescriptors:sortDescriptors]; //step3的输出
NSLog(@"\n\n\n按照拼音首字母后的NSString数组");
for(int i=;i<[chineseStringsArray count];i++){
ChineseString *chineseString=[chineseStringsArray objectAtIndex:i];
NSLog(@"原String:%@----拼音首字母String:%@",chineseString.string,chineseString.pinYin);
} //step4:如果有需要,再把排序好的内容从ChineseString类中提取出来
NSMutableArray *result=[NSMutableArray array];
NSMutableArray *pinYinResult=[NSMutableArray array];
for(int i=;i<[chineseStringsArray count];i++){
[result addObject:((ChineseString*)[chineseStringsArray objectAtIndex:i]).string];
[pinYinResult addObject:((ChineseString *)[chineseStringsArray objectAtIndex:i]).pinYin];
}
//Step4输出
NSLog(@"\n\n\n最终结果:");
for(int i=;i<[result count];i++){
NSLog(@"%@",[result objectAtIndex:i]);
} //得到名字排好序的数据源后,需要将这些球员对象根据名字的首字母,进行分段
NSMutableArray *arrAll = [NSMutableArray arrayWithCapacity:]; //遍历26个字母
for(NSString *aIndexTitle in _indexTitles)
{
arrTmp=[[NSMutableArray alloc]initWithCapacity:]; //遍历球员对象,找到那些名字是当前字母的球员,加到arrTmp中去
for (ChineseString *oneChineseString in chineseStringsArray) {
NSString *pinYin=oneChineseString.pinYin;
NSString *firstPinYin=[pinYin substringToIndex:]; //不区分大小写比较
if([[firstPinYin lowercaseString] hasPrefix:[aIndexTitle lowercaseString]])
{
[arrTmp addObject:oneChineseString];
}
}
[arrAll addObject:arrTmp];
}
//重置数据源,进行赋值 if(_datasource)
{
_datasource=nil;
}
_datasource = [[NSArray alloc] initWithArray:arrAll];
}

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

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return _indexTitles.count;
} //每段几行
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(!self.datasource)
{
return ;
} 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=;
for (NSString *aAlpha in _indexTitles) {
if ([aAlpha isEqualToString:title]) {
return count;
}
count++;
}
return ;
} -(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)名单的索引显示的更多相关文章

  1. IOS 表视图(UITableVIew)的使用方法(2)名单的分段显示

    我们可以采用名字分段法,名字分段会在之后的小节中显示,这是转而使用球员的角色分段发,以最直接的入手点讲解好UITableView的分段使用方法.本节示例时基于上节的SimpleTableViewCon ...

  2. IOS 表视图(UITableVIew)的使用方法(6)表视图的编辑功能(新增Add)

    表视图的新增功能和删除功能虽然目的不同,但是工作流程是相似的 下面列出在处理新增的回调函数时,与删除所不同的逻辑部分代码. 显示下过如下: #pragma mark #pragma mark Tabl ...

  3. iOS 表视图(UITableVIew)的使用方法(1)表视图的示例

    表视图继承自UIScrollView,所以有着大多UIScrollView的操作特性,诸如手指控制内容的滚动,内容视图到顶端或者低端时的自动反弹等.配合UINavigationController的导 ...

  4. IOS 表视图(UITableVIew)的使用方法(8)表视图的编辑功能(多选)

    在表视图的删除操作中,每次只能够对其中一个单元进行删除,如果想要同时删除多条记录,不得不挨个地进行标准的删除操作 所以如果能够实现多选的机制,无论是删除还是其他功能的嫁接,都会变得更加方便 当UITa ...

  5. IOS 表视图(UITableVIew)的使用方法(5)表视图的编辑功能(删除)

    默认的,如果表视图支持编辑,那用户可以通过两种方式来删除某些行,其一为单击左侧的红色按钮后行右侧显示“Delete”按钮,其二为在单元行上的手指向左滑动,“Delete”按钮也会出现供用户单击.无论哪 ...

  6. IOS 表视图(UITableVIew)的使用方法(7)表视图的编辑功能(拖拉调整排序位置)

    除了每个单元行左边的删除和新增图标,UITableView还支持在单元行的右侧显示一个供用户拖拉调整排序位置的控件. 不过如果要显示此控件,UITableView的数据源需要实现以下的方法. -(vo ...

  7. IOS 表视图(UITableVIew)的使用方法(4)自定义表视图单元

    UITableViewCell的自定义往往需要自建一个UITableViewCell的子类后进行作业.开发者可以选择通过xib或者直接在UITableViewCell的布局中进行UITableView ...

  8. IOS 表视图UITableView 束NSBundle

    今天搞了一下表视图UITableView 表视图是在以后应用程序开发中经常用到的一个视图,所以必须要熟练掌握 所获不多,对视图有了一个大概的了解 其中有用到NSBundle , 束   这个类 先说一 ...

  9. IOS开发之表视图(UITableView)

    IOS开发之表视图(UITableView)的基本介绍(一) (一):UITableView的基本概念 1.在IOS开发中,表视图的应用十分广泛和普及.因此掌握表视图的用法显得非常重要.一般情况下对于 ...

随机推荐

  1. Android @+id与@id的区别

      Android中的组件需要用一个int类型的值来表示,这个值也就是组件标签中的id属性值.id属性只能接受资源类型的值,也就是必须以@开头的值,例如,@id/abc.@+id/xyz等. 如果在@ ...

  2. Sicily 4495. Print permutations

    http://soj.me/4495 按字典序生成字符串的全排列 直接递归: #include <iostream> #include <string> #include &l ...

  3. Android sdk + PhoneGap 配置

    最近在学习这方面.   安卓sdk(下载地址百度谷歌即可) . 最新版的安卓sdk 自带ADT(基于eclipse) 开发工具 所以 我们不需要另外下载 eclipse 即可开始开发. 安卓个版本ap ...

  4. SQL学习之SELECT子句顺序

    下面来总计下之前的随笔中所说过的所有的SELECT子句的顺序. 子句 说明 是否必须使用 SELECT                  要返回的列或者表达式                      ...

  5. nodejs教程:安装express及配置app.js文件

    express.js是nodejs的一个MVC开发框架,并且支持jade等多种模板.下面简单来说说express的安装和app.js文件的配置,然后在今后的教程中一步一步使用express.js搭建个 ...

  6. 弹出窗口a标签写下载,再弹出窗口

    如果这个窗口是弹出出口,直接<a href="">点击下载<a>是不行的,得用js这样写,弹出并关闭,不然会回到首页,如果没有定义首页会报错,<a h ...

  7. GUI练习——列出指定目录内容

    需求: 一个窗体里.在文本框输入路径后,摁回车键或者点击"转到"按钮后: 若路径合法,程序会自动在文本域里显示该路径下的文件目录:若路径非法,则弹出对话框,告之你路径非法.点击&q ...

  8. 从零开始PHP学习 - 第三天

    写这个系列文章主要是为了督促自己  每天定时 定量消化一些知识! 同时也为了让需要的人 学到点啥~! 本人技术实在不高!本文中可能会有错误!希望大家发现后能提醒一下我和大家! 偷偷说下 本教程最后的目 ...

  9. ie7(z-index)

    父级元素加上position:relative;并设置z-index. 父级元素的z-index优先,子元素的z-index是相对于父级元素的index. <div style="po ...

  10. 使用Fiddler解析WCF RIA Service传输的数据

    原文 http://www.cnblogs.com/wintersun/archive/2011/01/05/1926386.html 使用Fiddler 2 解析WCF RIA Service传输的 ...