您的位置:首页 > 移动开发 > IOS开发

iOS 通讯录拼音检索

2016-04-13 20:18 609 查看
这周工作上安排做一个通讯录检索功能,在网上搜索了下,大都是拿到了用户名数组进行排序分组。

但是在实际工作中,我们拿到的数据经常是一个个用户的数据模型,比如 张三,13682549230,iOS程序员;李四,15782763542,Android程序员;这样按照姓名的排序方法,就很难同时对模型进行排序。于是我写了一个Demo,方便大家对数据模型进行排序并分组。效果如下:

下载地址:通讯录拼音首字母索引Demo下载地址





1、首先我对数据初始化,懒加载就不给大家看了

- (void)initData
{
self.dataArray = [[NSMutableArray alloc]init];
StaffModel *sModel0 = [[StaffModel alloc]init];
sModel0.name = @"张三(小小)";
sModel0.job = @"程序员33";
sModel0.phone = @"13682549233";

StaffModel *sModel1 = [[StaffModel alloc]init];
sModel1.name = @"李四";
sModel1.job = @"程序员44";
sModel1.phone = @"13682549244";

StaffModel *sModel2 = [[StaffModel alloc]init];
sModel2.name = @"王二小";
sModel2.job = @"程序员22";
sModel2.phone = @"13682549222";

StaffModel *sModel3 = [[StaffModel alloc]init];
sModel3.name = @"吴小六";
sModel3.job = @"程序员66";
sModel3.phone = @"13682549266";

StaffModel *sModel4 = [[StaffModel alloc]init];
sModel4.name = @"颜小七";
sModel4.job = @"程序员77";
sModel4.phone = @"13682549277";

StaffModel *sModel5 = [[StaffModel alloc]init];
sModel5.name = @"王小八";
sModel5.job = @"程序员88";
sModel5.phone = @"13682549288";

[self.dataArray addObject:sModel0];
[self.dataArray addObject:sModel1];
[self.dataArray addObject:sModel2];
[self.dataArray addObject:sModel3];
[self.dataArray addObject:sModel4];
[self.dataArray addObject:sModel5];

NSLog(@"dataArray---%@",self.dataArray);
}


2、导入pinyin 的第三方文件,并在控制器中引入 #import "ChineseString.h",多谢前辈写好。



3、抽取数据中的姓名,组成数组,对该数据中的文字首字符进行排序

for (int i = 0; i < self.dataArray.count; i ++) {
StaffModel *sModel = self.dataArray[i];
[self.nameArray addObject:sModel.name];
NSLog(@"name -- %@,%@",sModel.name,self.nameArray);
}

self.nameSortedArray = [ChineseString LetterSortArray:self.nameArray];

self.indexArray = [ChineseString IndexArray:self.nameArray];
NSLog(@"namerray,nameSortedArr---%@,%@",self.nameArray,self.nameSortedArray);


4、根据姓名,查找原来数组中对应的名字,并产生重新排序的数组

- (void)sortData
{
    //获取排序后的用户职位

    
    for (int i = 0; i < self.nameSortedArray.count; i ++) {
        NSArray *nameArray = self.nameSortedArray[i];
      
        NSMutableArray *jArr = [[NSMutableArray alloc]init];
        
        
        for (int j = 0; j < nameArray.count; j++) {
            NSString *name = nameArray[j];
            
            
            for (int m = 0; m < self.dataArray.count; m++) {
                
                StaffModel *sModel = self.dataArray[m];
                NSLog(@"name --%d,%d, %@,%@",self.dataArray.count,m, name, sModel.name);
                
                if ([sModel.name isEqualToString:name]) {//找到和名字匹配的模型,并添加
                    
                    [jArr addObject:sModel];
                    [self.dataArray removeObject:sModel];  //是匹配的,下次就不用查了
                    break;   //找到匹配的,本次就不继续往下查了,提高性能
                    
                }
                
            }
            
        }
        
       [self.sortedDataArray addObject:jArr];
       
    }
}


5、tableview数据的展示

#pragma mark - UITableViewDataSource

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

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSString *key = [self.indexArray objectAtIndex:section];
return key;
}

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

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[self.sortedDataArray objectAtIndex:section] count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
StaffModel *sModel = self.sortedDataArray[indexPath.section][indexPath.row];

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"];
}
cell.textLabel.text = sModel.name;
cell.detailTextLabel.text =sModel.job;
return cell;
}

#pragma mark - UITableViewDelegate
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
StaffModel *sModel = self.sortedDataArray[indexPath.section][indexPath.row];
DetailViewController *detailVc = [[DetailViewController alloc]init];
detailVc.staffModel = sModel;
[self presentViewController:detailVc animated:YES completion:nil];

}


6、注意事项

如果你的名字中包含 “()” 等特殊字符,请把下面框中的代码注释掉。

因为这行代码会把特殊字符过滤掉,这样那么根据姓名查找模型的算法就会找不到姓名,就无法显示到页面,或者程序崩溃。



7、titleIndex 贴心小事项

如果自己不设置索引文字和背景颜色,那么文字颜色默认为蓝色,北京颜色默认为白色;一般将北京颜色调为透明色

tableView.sectionIndexColor = [UIColor purpleColor];  //修改索引文字颜色
tableView.sectionIndexBackgroundColor = [UIColor clearColor];  //修改索引背景颜色
tableView.sectionIndexTrackingBackgroundColor = [UIColor greenColor];  //点击索引后,索引条的高亮颜色
tableView.sectionIndexMinimumDisplayRowCount = 4;  //当tableView总行数大于多少时,才显示索引条


其他代码不多累述,欢迎下载资源讨论:通讯录拼音首字母索引Demo下载地址

----------------------------------

增强版

你的老板可能会提出这样的需求:为什么索引条只显示3个字母,我要显示所有字母;

OK,你把sectionIndexTitlesForTableView 传入所有字母,可是这样点击某些字母,却没有跳转到相应的section,这个时候,我们需要用到 sectionForSectionIndexTitle 这个方法了。

1、添加26个字母的索引

1)你可以用这种方法:

-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
//    return self.indexArray;
return @[@"A",@"B",@"C",@"D",@"E",@"F",@"G",
@"H",@"I",@"J",@"K",@"L",@"M",@"N",
@"O",@"P",@"Q",@"R",@"S",@"T",
@"U",@"V",@"W",@"X",@"Y",@"Z"];
}


2)当然你也可以选择更高端的方法:使用ASCII码

这里命名A--Z的索引,为假索引

-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
//    return self.realIndexArray;

self.fakeIndexArr = [[NSMutableArray alloc]init];
for(char c ='A';c<='Z';c++)
{

//当前字母
NSString *letter = [NSString stringWithFormat:@"%c",c];

if (![letter isEqualToString:@"I"]&&![letter  isEqualToString:@"O"]
&&![letter isEqualToString:@"U"]&&![letter isEqualToString:@"V"]){

[self.fakeIndexArr addObject:[NSString stringWithFormat:@"%c",c]];

}

}
return self.fakeIndexArr;
}


2、返回点击索引字母跳转的sectionIndex

这里要进行一点逻辑处理,我的想法是:



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

{
NSLog(@"indexTitle -- %@",title);

//点击索引,列表跳转到对应索引的行
int realIndex = [self.realIndexArray indexOfObject:title];

if ([self.realIndexArray containsObject:title]) {
NSLog(@"找到匹配的索引 -- %d",realIndex);

}else{
NSLog(@"不存在这个索引,寻找正确索引");

for (int fakeIndex = [self.fakeIndexArr indexOfObject:title];fakeIndex < self.fakeIndexArr.count;fakeIndex ++ ) {

NSString *fakeLetter = [self.fakeIndexArr objectAtIndex:fakeIndex];

if ([self.realIndexArray containsObject:fakeLetter]) {
realIndex = [self.realIndexArray indexOfObject:fakeLetter];
//                NSLog(@"letterStr --- %@",letterStr);
NSLog(@"后面第一个在索引中的字母: fakeLetter,index -- %@,%d",fakeLetter,realIndex);
break;
}else{
realIndex = self.realIndexArray.count - 1;  //如果只有a.b.c,点击D,则显示C
NSLog(@"后面字母也不在索引中 realIndex --- %d",realIndex);
}
}
}

[tableView
scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:realIndex]
atScrollPosition:UITableViewScrollPositionTop animated:YES];

return realIndex;

}


----------------------------------

如果有更好的对模型中某个属性进行排序,进而对模型进行排序的方法,欢迎反馈!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: