(这里博主重新编辑了文章,增加了特殊字符开头的分组判定依据“#”)
闲来无事看到有人说苹果通讯录右侧字母的点击定位功能,所以就简单写了一个来给大家分享,先看下效果图:
旧图:

新图:

接着是代码部分,直接用新代码覆盖了,增加了更全的注释信息,理解起来更容易:

//
//  ViewController.m
//  通讯录右侧字母点击效果
//
//  Created by 刘浩浩 on 16/6/21.
//  Copyright © 2016年 CodingFire. All rights reserved.
//#import "ViewController.h"@interface ViewController ()<UITableViewDelegate,UITableViewDataSource>
{//非汉字和字母开头NSMutableArray *jingChar;//所有联系人名字头字母NSMutableArray *charSectionArray;//所有联系人按照头字母分组NSMutableArray *_dataArray;UITableView *_tableView;
}
@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view, typically from a nib._dataArray = [[NSMutableArray alloc]init];charSectionArray = [[NSMutableArray alloc]init];jingChar = [[NSMutableArray alloc]init];//获取plist中的数据NSString *plistPath = [[NSBundle mainBundle]pathForResource:@"PeopleNumber" ofType:@"plist"];NSArray *plistArray = [NSArray arrayWithContentsOfFile:plistPath];NSMutableArray *charArray = [[NSMutableArray alloc]init];//获取联系人名字首字母并排序for (int i = 0; i < plistArray.count; i++) {NSString *plistIndex = plistArray[i];NSString *charFirst = [self firstCharactor:plistIndex];if ([self MatchLetter:charFirst]) {[charArray addObject:charFirst];}else{//将不是字母和文字开头的特殊字符打头的string加入#分组[jingChar addObject:plistArray[i]];}}//去除重复的objectNSSet *set = [NSSet setWithArray:charArray];//将NSSet转化回数组NSArray *sortDesc = @[[[NSSortDescriptor alloc] initWithKey:nil ascending:YES]];NSArray *sortSetArray = [set sortedArrayUsingDescriptors:sortDesc];//按A-Z排序NSArray *charAllArray = [sortSetArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2){return [obj1 compare:obj2 options:NSNumericSearch];}];//将联系人根据名字首字母进行分组/**此分组方法最大的缺陷就是需要一个个比对,所以属于耗时操作,运行后并不会立马显示数据,而是需要一定时间的数据处理,如果要用的话最好在存储方法上开线程后台比对处理来存储,或者预处理,不要在进入这个界面时才处理*/for (int i = 0; i < charAllArray.count; i++) {NSString *charStr = charAllArray[i];NSMutableArray *subCharArray=[[NSMutableArray alloc]init];for (int j=0; j < plistArray.count; j++) {NSString *subCharStr = [self firstCharactor:plistArray[j]];if ([charStr isEqualToString:subCharStr]) {[subCharArray addObject:plistArray[j]];}}[_dataArray addObject:subCharArray];}[_dataArray addObject:jingChar];charSectionArray=[NSMutableArray arrayWithArray:charAllArray];[charSectionArray addObject:@"#"];[self creatTableView];}
#pragma mark 正则表达式
-(BOOL)MatchLetter:(NSString *)str
{//判断是否以字母开头NSString *ZIMU = @"^[A-Za-z]+$";NSPredicate *regextestA = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", ZIMU];if ([regextestA evaluateWithObject:str] == YES)return YES;elsereturn NO;
}-(BOOL)isChineseFirst:(NSString *)firstStr
{//是否以中文开头(unicode中文编码范围是0x4e00~0x9fa5)int utfCode = 0;void *buffer = &utfCode;NSRange range = NSMakeRange(0, 1);//判断是不是中文开头的,buffer->获取字符的字节数据 maxLength->buffer的最大长度 usedLength->实际写入的长度,不需要的话可以传递NULL encoding->字符编码常数,不同编码方式转换后的字节长是不一样的,这里我用了UTF16 Little-Endian,maxLength为2字节,如果使用Unicode,则需要4字节 options->编码转换的选项,有两个值,分别是NSStringEncodingConversionAllowLossy和NSStringEncodingConversionExternalRepresentation range->获取的字符串中的字符范围,这里设置的第一个字符 remainingRange->建议获取的范围,可以传递NULLBOOL b = [firstStr getBytes:buffer maxLength:2 usedLength:NULL encoding:NSUTF16LittleEndianStringEncoding options:NSStringEncodingConversionExternalRepresentation range:range remainingRange:NULL];if (b && (utfCode >= 0x4e00 && utfCode <= 0x9fa5))return YES;elsereturn NO;
}
#pragma mark - creatTableView
- (void)creatTableView
{_tableView = [[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStyleGrouped];_tableView.delegate = self;_tableView.dataSource = self;[self.view addSubview:_tableView];[_tableView reloadData];
}
//获取拼音首字母(传入汉字字符串, 返回大写拼音首字母)
- (NSString *)firstCharactor:(NSString *)aString
{//转成了可变字符串NSMutableString *str = [NSMutableString stringWithString:aString];//先转换为带声调的拼音CFStringTransform((CFMutableStringRef)str,NULL, kCFStringTransformMandarinLatin,NO);//再转换为不带声调的拼音CFStringTransform((CFMutableStringRef)str,NULL, kCFStringTransformStripDiacritics,NO);//转化为大写拼音NSString *pinYin = [str capitalizedString];//获取并返回首字母return [pinYin substringToIndex:1];
}#pragma mark - UITableViewDelegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{return [_dataArray[section] count];
}- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{return charSectionArray.count;
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{return 44;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{return 0.0001;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{return 30;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{return [NSString stringWithFormat:@"%@",charSectionArray[section]];
}
//索引
//一共有两个方法
//第一个方法用返回显示的索引是什么
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{return charSectionArray;
}//第二个方法的作用当点击索引时,跳到对应分组
-(NSInteger) tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{//返回当前索引在tableView分组上的位置return index;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];if (!cell) {cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];}cell.textLabel.text=[[_dataArray objectAtIndex:indexPath.section]objectAtIndex:indexPath.row];return cell;
}
- (void)didReceiveMemoryWarning {[super didReceiveMemoryWarning];// Dispose of any resources that can be recreated.
}@end

Demo下载地址:https://github.com/codeliu6572/Apple_mail_list

iOS开发 - 模拟苹果通讯录相关推荐

  1. ios开发基础之通讯录系统实战-20

    ios开发基础之通讯录系统实战 基础知识 OC 基础 segue 的使用.delegate 代理的使用 自定义代理.面向对象思想 沙盒容器的数据持久化方案, controller 之间的跳转 ,登录方 ...

  2. 李洪强iOS开发之苹果企业开发者账号申请流程

    李洪强iOS开发之苹果企业开发者账号申请流程 一. 开发者账号类型选择 邓白氏码 DUNS number,是Data Universal Numbering System的缩写,是一个独一无二的9位数 ...

  3. iOS开发:苹果应用商店审核指南中文翻译

    前言 感谢您付出宝贵的才华与时间来开发iOS应用程程序.从职业与报酬的角度而言,这对于成千上万的开发员来说一直都是一项值得投入的事业.我们希望帮助您加 入这个成功的组织.这是我们首次发布<应用程 ...

  4. iOS开发创建苹果证书、制作p12证书流程

    ios开发的打包证书,官方提供的方法是需要使用mac电脑,先创建csr文件,再去苹果开发者中心生成cer证书,然后再将cer证书导入mac系统,再从mac系统导出p12,整个过程不仅需要mac电脑,而 ...

  5. iOS开发——高级技术通讯录功能的实现

    通讯录功能的实现 iOS 提供了对通讯录操作的组建,其中一个是直接操作通讯录,另一个是调用通讯录的 UI 组建.实现方法如下: 添加AddressBook.framework到工程中. 代码实现: 1 ...

  6. iOS开发 IAP苹果内购

    为什么80%的码农都做不了架构师?>>>    1.概念介绍 <1>苹果内购: App内购买是指在苹果的 App Store 中购买应用程序的方式. 在玩一些游戏类应用软 ...

  7. iOS开发:苹果开发者账号第一次新建APP ID以及创建App的步骤

    在iOS开发过程中,关于苹果开发者账号相关操作的知识点也是不可忽视的,尤其是对于一些刚接触苹果开发的开发者来说,更应该多了解一些关于苹果开发者账号的知识点,这样有利于App的测试和上架. 苹果开发者账 ...

  8. iOS开发-苹果开发者账号注册、申请续费整个流程

    一.注册Apple ID 注:申请Apple ID的时候,First Name与Last Name,要填写个人资料,不要填公司名,一定要填写正确 Personal Information First ...

  9. IOS开发之 ---- 苹果系统代码汉字转拼音

    NSString *hanziText = @"我是中国人";   if ([hanziText length]) {   NSMutableString *ms = [[NSMu ...

最新文章

  1. 军团要塞2正版服务器,专用服务器配置 - Official TF2 Wiki | Official Team Fortress Wiki
  2. 解决Jupyter notebook安装后不自动跳转网页的方法
  3. 工作总结20190121
  4. Centos 6.4 python 2.6 升级到 2.7一起的MySQLdb不能使用的解决问题
  5. 为什么两个controller的session的id不一样_我,为什么会离婚?我为什么离婚?
  6. ftp服务器、文件夹中带点文件删除方法
  7. 5个超实用抠图方法,哪个适用用哪个
  8. FLASH和EEPROM的区别和扩展
  9. windows安装配置jdk1.8
  10. HTML上下左右布局
  11. 华为畅享max什么时候鸿蒙,华为鸿蒙系统正式推送 具体怎么样及支持哪些手机带你前先看...
  12. 华为8c系统语言切换,华为荣耀畅玩8C双清教程_怎么清理缓存和恢复出厂设置
  13. 硬盘备份到新电脑,你需要知道这个技巧
  14. CF大陆斗C战士(三)
  15. 杭电2566_统计硬币——java
  16. qq/微信联合登录整体流程图!
  17. 马士兵 java se_马士兵javase(170804)
  18. OpenGL着色器透视变换实例-通过旋转平移调试着色器
  19. 红帽OpenStack私有云部署
  20. 比较知名的外包系统软件开发公司有哪些是哪个

热门文章

  1. mongodb的aggregate 用法
  2. 你真的理解 Vue Router 的路由模式吗?
  3. Asp.Net customErrors与httpErrors的区别 先看一下简单的对比
  4. 流程图用什么软件画?这三款工具很实用
  5. 响应式布局的常用解决方案对比(媒体查询、百分比、rem和vw/vh)
  6. matlab 图像归一化!!
  7. C4D渲染器到底该怎么选?
  8. 前端form表单提交的方式
  9. c语言中mikado_蜜蜂如何使用mikado方法
  10. glide-transformations 使用笔记