开发iOS通讯录项目,遇到一个tableview 索引的问题。
测试同学发现一个bug:添加一个名字为宽字符A不能归并到索引A的section中,而是使用了添加了一个叫A的索引,如图:
上图中:右侧索引尾部发生异常。ABX并没有归并到正常的索引中,而是出现在正常索引的Z和#之间了。
想了一下,应该是宽字符A和A的编码不一致导致的。
之前代码是这样的,看第二行使用正则表达式判断首字母是不是拉丁字母开头,然后标注此人是以某个字符开头的,代码如下:
NSPredicate* HanziPred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",@"[\u4e00-\u9fa5]"];
NSPredicate *EnglishPred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",@"^[A-Z].*$"];
NSPredicate *numberPred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",@"^[0-9].*$"];
if([EnglishPred evaluateWithObject: first]){//拉丁字母
self.firstLetter = self.latinString.length >0?[self.latinString substringToIndex:1]:@"#";
}
通过正则表达式,将first赋值给firstLetter。正则表达式果然很强大,竟然可以兼容宽字符和窄字符。这样导致A和A都符合正则,但是确是两个不同的字符。
我的解决办法是,事先创建一个静态全局字典,并初始化,在使用正则的时候,首先判断是否能从字典中匹配到宽字符,如果可以强制替换为窄字符。
static NSDictionary* widthLetter;
-(id)init{
self = [super init];
self.firstLetter = @"#";
widthLetter = @{@"A":@"A"
,@"B":@"B"
,@"C":@"C"
,@"D":@"D"
,@"E":@"E"
,@"F":@"F"
,@"G":@"G"
,@"H":@"H"
,@"I":@"I"
,@"J":@"J"
,@"K":@"K"
,@"L":@"L"
,@"M":@"M"
,@"N":@"N"
,@"O":@"O"
,@"P":@"P"
,@"Q":@"Q"
,@"R":@"R"
,@"S":@"S"
,@"T":@"T"
,@"U":@"U"
,@"V":@"V"
,@"W":@"W"
,@"X":@"X"
,@"Y":@"Y"
,@"Z":@"Z"};
return self;
}
if([EnglishPred evaluateWithObject: first]){//拉丁字母
//兼容宽字符
if (widthLetter[first]) {
self.firstLetter = self.latinString.length >0?widthLetter[first]:@"#";
}else{
self.firstLetter = self.latinString.length >0?first:@"#";
}
}
A和A都能进入到A的索引中,如图:
tableview中index对英文字符汉字字符(窄字符宽字符)处理
原文:http://blog.csdn.net/hherima/article/details/42806147