I. 用戶在搜索框中,輸入關鍵字進行檢索時,APP對搜索結果進行顯示,有如下兩種狀況:ios
1. 匹配一次,如檢索關鍵字爲人名git
這種狀況,實現比較容易。寫一個UILabel的category, 用rangeOfString這個方法找到須要高亮的range, 最後設置attributedString便搞定。源碼以下:github
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的顏色能夠改爲你想要的任意色,我當前指定爲藍色。web
或者你能夠在此link UILabel+Highlight下,查看源碼。正則表達式
2. 匹配次數爲n次,通常此時檢索結果爲後臺返回,如每日進行google search時,高亮顯示全部匹配關鍵字(徹底匹配關鍵字場景)算法
假定場景服務器返回子串相似於此: express
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開源項目,真心不錯,由於這個平臺已經幫咱們過濾一遍了。