天天看点

高亮显示UILabel中的子串

I. 用户在搜索框中,输入关键字进行检索时,APP对搜索结果进行显示,有以下两种情况:

1. 匹配一次,如检索关键字为人名

这种情况,实现比较容易。写一个UILabel的category, 用rangeOfString这个方法找到需要高亮的range, 最后设置attributedString便搞定。源码如下:

1 - (void)highlightString:(NSString *)str
 2 
 3 {
 4 
 5     if (self.text.length <= 0 || str.length <= 0) {
 6 
 7         return;
 8 
 9     }
10 
11     
12 
13     NSString *scopeStr = self.text;
14 
15     NSRange range = [scopeStr rangeOfString:str options:NSCaseInsensitiveSearch];
16 
17     
18 
19     //color
20 
21     NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:scopeStr];
22 
23     [attributedStr addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:range];
24 
25     
26 
27     [self setAttributedText:attributedStr];
28 
29 }      

highlight的颜色可以改成你想要的任意色,我当前指定为蓝色。

或者你可以在此link UILabel+Highlight下,查看源码。

2. 匹配次数为n次,一般此时检索结果为后台返回,如每日进行google search时,高亮显示所有匹配关键字(完全匹配关键字场景)

假定场景服务器返回子串类似于此: 

eg: xxxx<em>xxxx</em>xxxxx<em>xxxx</em>xxxxx<em>xxxx</em>xxxxx   ---> originStr

 起始标识: <em>  ---> beginTag

 结束标识: </em> ---> endTag

 目的:高亮在<em>和</em>中间部分的子串

 中间关键变量定于:

 1. tagArr: array of NSRange, 用于标识出originStr中所有成对出现的beginTag和endTag讯息

 2. strArr: array of NSRange, 最终画在label上的string

 3. colorArr: array of NSRange, 标识所有高亮位置

 关键问题是:如何高效算出tagArr?

 我目前做法是:从originStr的index=0开始成对找第一对的beginTag和endTag信息,然后将index赋值到第一个endTag的位置找第二对,以此类推。

具体源码大家查看此link UILabel+Highlight,因为代码较多,不方便黏贴下来。这个功能实现是没有问题的,因为我在项目中便是用此方法实现的,但其存在优化空间。

II. highlight字符串基础上延伸至RichText

1. 类似于微信,在聊天对话框中显示表情

open source link : https://github.com/molon/MLEmojiLabel

我reveiw其源码出发点有两个:

  a. 如何找到所有表情位置?

  起初我想看看它用到什么算法,可以有助于我优化I.2中的问题。不过,此处用正则表达式来找到所有表情的位置信息的。

  查看MLEmojiLabel.m中此方法: - mutableAttributeStringWithEmojiText:

  ---> kSlashEmojiRegularExpression() ---> @"/:[\\x21-\\x2E\\x30-\\x7E]{1,8}" ---> 此正则表达式TBD(TO BE Discussed)?

  

  另: 表情与icon的对应,用plist进行存储。

  eg: key    : value

    /:eat  : Expression_b2 (icon's name)

  b. expression icon如何绘制到label上?

  查看MLEmojiLabel.m中此方法: - drawOtherForEndWithFrame:inRect: context: , 其中都是使用CoreText实现的。

2. TTTAttributedLabel for RichText

link : https://github.com/TTTAttributedLabel/TTTAttributedLabel

TTTAttributedLabel算是RichText比较常用的开源库了,MLEmojiLabel便是继承这个类的。它基本实现我们对富文本的一般操作,而不需要用到CoreText。比如:显示link,号码等等,以及对应的一些touch事件。可以用CoacoPods导入。顺便题外一下CoacoPods这个工具,用它检索好得ios开源项目,真心不错,因为这个平台已经帮我们过滤一遍了。

转载于:https://www.cnblogs.com/ouyangfang/p/6641009.html