【问题描述】
开发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的索引中,如图:
时间: 2024-10-20 15:45:21