iOS 实现类似通讯录按拼音排序 - PinYin4Objc
最近项目中需要实现类似通讯录那样按拼音进行排序以及索引列表的显示的功能,这里使用了 PinYin4Objc 这个库来实现此功能。
PinYinObjc是一个效率很高的汉字转拼音类库,智齿简体和繁体中文,有如下特点:
1、效率高,使用数据缓存,第一次初始化以后,拼音数据存入文件缓存和内存缓存,后面转换效率大大提高;
2、支持自定义格式化,拼音大小写等等;
3、拼音数据完整,支持中文简体和繁体,与网络上流行的相关项目比,数据很全,几乎没有出现转换错误的问题.
在项目中使用可以cocoapods来管理:pod 'PinYin4Objc', '~> 1.1.1'
也可以直接去github上下载源码:PinYinObjc
项目需求:
获取一个销售人员的列表,并且把自己放到第一个,用#标示,如图:
代码实现过程:
1、获取销售人员列表数据(这里是通过网络请求获取):
///查询列表数据
- (void)fetchSallersList {
[_listAPI startWithCompletionWithSuccess:^(id responseDataDict) {
[self.tableView.mj_header endRefreshing];
///解析数据
NSMutableArray *array = [SCSalesModel mj_objectArrayWithKeyValuesArray:responseDataDict];
self.resultList = [array mutableCopy];
///处理数据
[self conversionResultData];
[self changeResultList];
///刷新UI
[self reloadUI];
} failure:^(NSError *error) {
[self.tableView.mj_header endRefreshing];
[SCAlertHelper handleError:error];
}];
}
2、将每个销售人员的名字转成拼音并转成大写字母:
HanyuPinyinOutputFormat *outputFormat=[[HanyuPinyinOutputFormat alloc] init];
[outputFormat setToneType:ToneTypeWithoutTone];
[outputFormat setVCharType:VCharTypeWithV];
[outputFormat setCaseType:CaseTypeUppercase];
[self.resultList enumerateObjectsUsingBlock:^(SCSalesModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSString *pinyin = [[PinyinHelper toHanyuPinyinStringWithNSString:obj.salesName withHanyuPinyinOutputFormat:outputFormat withNSString:@""] uppercaseString];
SCLog(@"名字转拼音大写:%@", pinyin);
obj.pinyinName = pinyin;
}];
3、按照拼音字段pinyinName进行排序:
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"pinyinName" ascending:YES];
NSArray *array = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[self.resultList sortUsingDescriptors:array];
4、定义一个全局变量 dataDictionary 来组织数据结构
key: 将汉字转完拼音后的第一个字母, 也就是上图section中的 A、B、C...
value: 是一个成员数组,存放每个section下的成员列表
key: 将汉字转完拼音后的第一个字母, 也就是上图section中的 A、B、C...
value: 是一个成员数组,存放每个section下的成员列表
_dataDictionary = [[NSMutableDictionary alloc] init];
//存放每个 section 下的成员数组
NSMutableArray *currentArray = nil;
//用于获取拼音中第一个字母
NSRange aRange = NSMakeRange(0, 1);
NSString *firstLetter = nil;
//遍历成员列表组织数据结构
for (SCSalesModel *seller in self.resultList) {
//如果是本人,则暂时不放如 dataDictionary 中
if ([seller.salesId isEqualToString:[SCUserModel currentLoggedInUser].userId]) {
_owerSaller = seller;
continue;
}
//获取拼音中第一个字母,如果已经存在则直接将该成员加入到当前的成员数组中,如果不存在,创建成员数据,添加一个 key-value 结构到 dataDictionary 中
firstLetter = [seller.pinyinName substringWithRange:aRange];
if ([_dataDictionary objectForKey:firstLetter] == nil) {
currentArray = [NSMutableArray array];
[_dataDictionary setObject:currentArray forKey:firstLetter];
}
[currentArray addObject:seller];
}
5、再定义一个全局变量 allKeys 用于显示索引列表中索引:
_allKeys = [[NSMutableArray alloc] initWithArray:[[_dataDictionary allKeys] sortedArrayUsingFunction:sortObjectsByKey context:NULL]];
//然后将本人加入到排好序 allKeys 的最前面
if (_owerSaller) {
[_allKeys insertObject:@"#" atIndex:0];
[_dataDictionary setObject:[NSArray arrayWithObjects:_owerSaller, nil] forKey:@"#"];
}
//其中sortObjectsByKey是排序方法
NSInteger sortObjectsByKey(id user1, id user2, void *context) {
NSString *u1,*u2;
//类型转换
u1 = (NSString*)user1;
u2 = (NSString*)user2;
return [u1 localizedCompare:u2];
}
6、最后就是通过 allKeys 和 dataDictionary 进行配置一下 tableview 的各个代理就 OK 了。
借鉴:http://www.cnblogs.com/jerryfeng/p/4288244.html
菜鸟笔记!希望对你有帮助!