GeekBand.iOS-UILocalized​Indexed​Collation

2016/3/28 posted in  iOS学习笔记  

tableView中区域索引标题(section index titles)。它们是在列表右边纵向排列的字母,你可以在电话本联系人界面和音乐曲库界面中看到它们。
Section Index Titles Example
当用户在那个列表里向下移动手指时,列表会在对应的区域间跳动。这会使得冗长的列表视图变得超级好用。
可以通过实现下列 UITableViewDataSource 中的方法来显示区域索引标题:

//返回一个区域索引标题的数组,用于在列表右边显示,例如字母序列 A...Z 和 #。区域索引标题很短,通常不能多于两个 Unicode 字符。
-sectionIndexTitlesForTableView:
//返回当用户触摸到某个索引标题时列表应该跳至的区域的索引。 
-tableView:sectionForSectionIndexTitle:atIndex: 

我们肯定不想自己去生成这个字母列表。对于不同的地区来说,字母的顺序,甚至「字母」,的意义都会大不相同。此时UILocalizedIndexedCollation来拯救我们了。
UILocalizedIndexedCollation 是一个帮助我们组织列表数据的类,它能够根据地区来生成与之对应区域索引标题。不需要直接创建它的对象,我们可以通过 UILocalizedIndexedCollation +currentCollation 获得一个对应当前地区的单例对象。
UILocalizedIndexedCollation 的首要任务就是决定对于当前地区区域索引标题应该是什么,我们可以通过 sectionIndexTitles 属性来获得它们。

下表可以帮助你更好的了解不同地区之间区域索引标题的差别。

Locale Section Index Titles
en_US 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, #
ja_JP 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, あ, か, さ, た, な, は, ま, や, ら, わ, #
sv_SE 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, Å, Ä, Ö, #
ko_KO 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, ㄱ, ㄴ, ㄷ, ㄹ, ㅁ, ㅂ, ㅅ, ㅇ, ㅈ, ㅊ, ㅋ, ㅌ, ㅍ, ㅎ, #
ar_SA 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, آ, ب, ت, ث, ج, ح, خ, د, ذ, ر, ز, س, ش, ص, ض, ط, ظ, ع, غ, ف, ق, ك, ل, م, ن, ه, و, ي, #

有了这些区域标题,下一步就是判断每个模型对象分别对应哪个区域了。这可以通过实现 -sectionForObject:collationStringSelector: 做到。这个方法返回 NSInteger 类型的索引,它对应了模型对象的指定方法的返回值。方法名称可以为 localizedName、title 甚至 description 等。

显而易见,列表数据源中会有一个数组,它对应了列表中有多少区域,数组元素表示区域中的每一行。由于整理工作是由 UILocalizedIndexedCollation 来做的,因此理所当然地,也应该由它来为每个区域中的行进行排序。和 -sectionForObject:collationStringSelector: 的实现方式类似,– sortedArrayFromArray:collationStringSelector: 可以为我们基于模型对象的本地化标题来排列模型对象。

最后,数据源应该实现 -tableView:sectionForSectionIndexTitle:atIndex: 方法,这样当我们触摸到区域索引标题时,能够让列表调至对应的区域。UILocalizedIndexedCollation -sectionForSectionIndexTitleAtIndex: 可以轻松帮我们做到。

都说完了,下边是列表数据源的一个常见实现:

//数据预处理
-(NSMutableArray *)getSectionsArray{
    UILocalizedIndexedCollation* collation = [UILocalizedIndexedCollation currentCollation];
    //获得索引数和section标题数
    NSInteger index, sectionTitlesCount = [[collation sectionTitles] count];
    //临时数据,存放section对应的联系人数组数据
    NSMutableArray *newSectionsArray = [[NSMutableArray alloc] initWithCapacity:sectionTitlesCount];
    //设置sections数组初始化:元素包含联系人数据的空数据
    for (index = 0; index < sectionTitlesCount; index++) {
        NSMutableArray *array = [[NSMutableArray alloc] init];
        [newSectionsArray addObject:array];
    }
    for (Linkman *linkman in self.allLinkmen) {
        
        //根据Linkman的name,获得对应的的section number
        NSInteger sectionNumber = [collation sectionForObject:linkman collationStringSelector:@selector(name)];
        //获得section的数组
        NSMutableArray *tempSections = [newSectionsArray objectAtIndex:sectionNumber];
        //添加内容到section中
        [tempSections addObject:linkman];
    }
    return newSectionsArray;
}





//数据容器操作
//返回索引的title值
-(NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView{
    return [[UILocalizedIndexedCollation currentCollation] sectionIndexTitles];
}
//设置section的header的title值
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
    return [UILocalizedIndexedCollation currentCollation].sectionTitles[section];
}
//点击索引的位置移动
-(NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index{
    return [[UILocalizedIndexedCollation currentCollation] sectionForSectionIndexTitleAtIndex:index];
}