本地化下按首字母分組排序的神器——UILocalizedIndexedCollation


  最近在整一個很簡單的通訊錄相關的項目,通訊錄當然就少不了按首字母或者漢字拼音首字母分組排序索引。因為按照我一貫的的做法,都是想要做成更通用的、支持本地化的,所以這就糾結了,世界各地的語言啊我去,我頂多也就認識中文和英語,這就不能用以前的那些比如把漢字轉成拼音再排序的方法了,效率不高不說,對其他國家的本地化更是行不通。一個偶然的機會,我才發現SDK里已經提供了一個實現此功能的神器——UILocalizedIndexedCollation。

  首先提一下,UILocalizedIndexedCollation的分組排序是建立在對對象的操作上的。下邊我會舉個栗子講解一下。首先已知有一個Person類:

1 @interface Person : NSObject
2 @property(nonatomic, strong) NSString *name;
3 @end

然后初始化一些對象存入一個數組(注:為了后續說明方便,我直接拿name的值來表示Person類的對象,實際編碼中是要用對象!如下列<林丹>表示p.name = @"林丹"的Person類對象p

1 NSArray *srcArray = @[<林榮>, <林丹>, <周董>, <周樹人>, <周傑倫>, <阿華>];

先將UILocalizedIndexedCollation初始化,

1 UILocalizedIndexedCollation *collation = [UILocalizedIndexedCollation currentCollation];

可以看出來這是一個單例,它會根據不同國家的語言初始化出不同的結果。如中文和英文的得到的就是A~Z和#,日語的就是A~Z,あ, か, さ, た, な, は, ま, や, ら, わ和#。下邊我就以最熟悉的中文環境為例,直接上代碼了,注意看注釋部分的講解

 1 //得出collation索引的數量,這里是27個(26個字母和1個#)
 2 NSInteger sectionTitlesCount = [[collation sectionTitles] count];
 3 
 4 //初始化一個數組newSectionsArray用來存放最終的數據,我們最終要得到的數據模型應該形如@[@[以A開頭的數據數組], @[以B開頭的數據數組], @[以C開頭的數據數組], ... @[以#(其它)開頭的數據數組]]
 5 
 6 NSMutableArray *newSectionsArray = [[NSMutableArray alloc] initWithCapacity:sectionTitlesCount];
 7     
 8 //初始化27個空數組加入newSectionsArray
 9 for (NSInteger index = 0; index < sectionTitlesCount; index++) {
10     NSMutableArray *array = [[NSMutableArray alloc] init];
11     [newSectionsArray addObject:array];
12 }
13     
14 //將每個人按name分到某個section下
15 
16 for (Person *p in srcArray) {
17   //獲取name屬性的值所在的位置,比如"林丹",首字母是L,在A~Z中排第11(第一位是0),sectionNumber就為11
18     NSInteger sectionNumber = [collation sectionForObject:p collationStringSelector:@selector(name)];
19   //把name為“林丹”的p加入newSectionsArray中的第11個數組中去
20     NSMutableArray *sectionNames = newSectionsArray[sectionNumber];
21     [sectionNames addObject:p]; 
22 }
23     
24 //對每個section中的數組按照name屬性排序
25 for (NSIntger index = 0; index < sectionTitlesCount; index++) {
26     NSMutableArray *personArrayForSection = newSectionsArray[index];
27     NSArray *sortedPersonArrayForSection = [collation sortedArrayFromArray:personArrayForSection collationStringSelector:@selector(name)];
28     newSectionsArray[index] = sortedPersonArrayForSection;
29 }

最終把newSectionsArray應該形如@[@[<阿華>], @[], @[], ... @[<林丹>, <林榮>], ... @[<周董>, <周傑倫>, <周樹人>], @[]]

后續工作就是把這個數組作為數據源與UITableView通過tableView的Delegate關聯起來了,部分如下,在此不再贅述

 1 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
 2     return [collation sectionTitles][section];
 3 }
 4 
 5 - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
 6     return [collation sectionIndexTitles];
 7 }
 8 
 9 - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
10     return [collation sectionForSectionIndexTitleAtIndex:index];
11 }

  不過呢,使用這個UILocalizedIndexedCollation有一個缺點就是不能區分姓氏中的多音字,比如“曾”會被分到"C"組去,不知道大家有沒有基於此的好方法在下邊回復。下邊是蘋果官方示例,其中第3個是關於UILocalizedIndexedCollation的,可以下載下來學習一下http://developer.apple.com/library/ios/samplecode/TableViewSuite/Introduction/Intro.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM