当数据量特别大时,简单地以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插件化-apkplugdemo源代码阅读指南-10

    阅读本节内容前可先了解 apkplug基础教程 本教程是基于apkplug V1.6.8 版本号编写  最新开发方式以官网为准 可下载最新的apkplugdemo源代码http://git.oschi ...

  2. Android Intent的几种用法总结【转】

    Intent应该算是Android中特有的东西.你可以在Intent中指定程序要执行的动作(比如:view,edit,dial),以及程序执行到该动作时所需要的资料.都指定好后,只要调用startAc ...

  3. loading android

    drawal/loading.xml <?xml version="1.0" encoding="utf-8"?><animated-rota ...

  4. onclick=‘’return false“

    文章来自  http://www.cnblogs.com/hellen-li/archive/2010/10/22/1858422.html checkbox没有readOnly属性,可以这样让它保持 ...

  5. jQuery Mobile组件

    一.页面 jQuery Mobile 应用了 HTML5 标准的特性,在结构化的页面中完整的页面结构分为header.content.footer 这三个主要区域. 在body 中插入内容块: < ...

  6. js 下拉框效果

    <script type="text/javascript"> window.onload = function () { ]; ]; var aLi = oSub.g ...

  7. Struts1、Struts2的线程安全问题

    Struts 1.x和Struts 2的Action是不是线程安全的? Struts 1.x在第一次请求某个Action时,会创建这个Action实例.但之后再请求该Action实例时,就用之前创建好 ...

  8. 修改Eclipse的WorkSpace保持数[转载]

    最近用Eclipse开发特别多,我个人习惯每一个项目一个WorkSpace,这样的话代码干净.而且当项目之前编码规范不一样时,也不会彼此影响.但项目一多,Eclipse默认只保存5个WorkSpace ...

  9. NAND Flash中常用的纠错方式(ECC算法)

    Hanming,RS,BCH —— NAND Flash中常用的纠错方式 因为闪存中会有出错的可能,如果没有使用ECC模块,读出的数据和写入的数据会有不匹配的可能,也许一个文件中只有一两个bit不匹配 ...

  10. Android快速开发框架——AndroidAnnotations(Code Diet)

    简介:AndroidAnnotations是一个依赖注入方式来简化代码结构 ,快速开发的开源框架,使结构代码更清晰,减少代码重复性.对今后我们做自动化测试和自动化埋点开发都会提高开发效率.跟我们之前使 ...