背景
最近做的搜索相关模块,用到对搜索关键字进行高亮处理的功能,由于需要处理的位置较多,就实现了一个通用方法,以方便调用。
由于关键字经过拆分可能成为多个分词组成的数组,所以需要同时对多个词进行匹配处理。
思路
- 字符串展示时某些词颜色不同可以使用NSMutableAttributedString类型,添加不同颜色属性实现
- 关键字匹配可以使用componentsSeparatedByString方法对原字符串使用关键字进行拆分,拆分后的数组如果有数据,即为命中,再对拆分后的数组逐项处理,得出关键字的位置
- 多个关键字可以多次重复上述第2步,分别进行处理,并不互相影响
- 得到关键字位置后,使用NSMutableAttributedString的添加属性的方法对字符串进行处理
- 由于某些情况下,可能只需要对字符串中的个别位置进行匹配,因此引入一个有效范围的参数进行控制,只有有效范围内的部分才有可能进行匹配变色
实现
根据以上思路,实现NSString的一个Catagory,主要方法如下
- (NSMutableAttributedString *)atrributeStringWithkeyWordsArr:(NSArray *)kwArr keyWordsColor:(NSString *)colorStr effectiveRange:(NSRange)effRange {
if (self.length == 0) {
return [[NSMutableAttributedString alloc] initWithString:@""];
}
if (kwArr.count == 0) {
return [[NSMutableAttributedString alloc] initWithString:self];
}
NSString *lowerText = [self lowercaseString];
NSMutableAttributedString *muAtt = [[NSMutableAttributedString alloc] initWithString:self];
for (NSString *keyword in kwArr) {
if (keyword.length == 0) {
continue;
}
NSString *lowerKey = [keyword lowercaseString];
NSArray *component = [lowerText componentsSeparatedByString:lowerKey];
NSInteger d = 0;
for (int i = 0; i < component.count - 1; i++) {
NSString *sepa = component[i];
NSInteger index = (d += sepa.length);
d += lowerKey.length;
NSRange highRange = NSMakeRange(index, lowerKey.length);
//只有生效区域内的才变色
if (NSLocationInRange(index, effRange) && (NSMaxRange(highRange) <= NSMaxRange(effRange))) {
[muAtt addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithHexString:colorStr] range:highRange];
}
}
}
return muAtt;
}