在上一篇博客中山寨了一下新浪微博,在之后的博客中會(huì)對(duì)上一篇代碼進(jìn)行優(yōu)化和重用,上一篇的微博請(qǐng)求的文字中有一些表情沒(méi)做處理,比如帶有表情的文字是這樣的“我要[大笑],[得意]”。顯示的就是請(qǐng)求的字符串,那么我們?nèi)绾伟盐淖衷诒镜剞D(zhuǎn)換成表情呢?下面將要說(shuō)一下顯示表情的解決方案。
要用到的知識(shí):IOS開(kāi)發(fā)中的資源文件.plist, 可變的屬性字符串,TextView和正則表達(dá)式的使用。
解決的整體思路:把源字符串同過(guò)正則匹配獲取到每個(gè)表情的range, 再通過(guò)range獲取元字符串中的表情字符串,如[哈哈], 在把[哈哈] 和我們.plist中item下的chs字段匹配,然后獲取對(duì)應(yīng)的圖片名,獲取圖片后把圖片轉(zhuǎn)換成可變字符串的附件,然后做一個(gè)替換即可。先這么大致一說(shuō),下面會(huì)詳細(xì)的講解一下。
1.要想在我們手機(jī)上顯示網(wǎng)絡(luò)請(qǐng)求的表情,首先我們本地得有相應(yīng)的資源文件,在.plist文件中又我們想要的東西,其中存儲(chǔ)的東西如下所示,整個(gè)root是一個(gè)數(shù)組,數(shù)組中的item是一個(gè)字典,字典中存放的時(shí)文字到圖片名的一個(gè)映射,當(dāng)然啦,圖片名和我們本地資源的圖片名相同。截圖如下

2.如何從.plist文件中獲取數(shù)據(jù)呢?先通過(guò)bundle獲取資源文件的路徑,在通過(guò)文件路徑創(chuàng)建數(shù)組,數(shù)組中存儲(chǔ)的數(shù)據(jù)就是文件中的內(nèi)容代碼如下:
//加載plist文件中的數(shù)據(jù) NSBundle *bundle = [NSBundle mainBundle]; //尋找資源的路徑 NSString *path = [bundle pathForResource:@"emoticons" ofType:@"plist"]; //獲取plist中的數(shù)據(jù) NSArray *face = [[NSArray alloc] initWithContentsOfFile:path];
3.生成我們的測(cè)試字符串,最后一個(gè)不是任何表情,不做替換。
//我們要顯示的字符串(模擬網(wǎng)路請(qǐng)求的字符串格式) NSString *str = @"我[圍觀]你[威武]你[嘻嘻]我[愛(ài)你]你[兔子]我[酷]你[帥](méi)我[思考]你[錢(qián)][123456]";
4.把上面的str轉(zhuǎn)換為可變的屬性字符串,因?yàn)槲覀円每勺兊膶傩宰址赥extView上顯示我們的表情圖片,轉(zhuǎn)換代碼如下:
//創(chuàng)建一個(gè)可變的屬性字符串 NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:str];
5.進(jìn)行正則匹配,獲取每個(gè)表情在字符串中的范圍,下面的正則表達(dá)式會(huì)匹配[/*],所以[123567]也會(huì)被匹配上,下面我們會(huì)做相應(yīng)的處理
//正則匹配要替換的文字的范圍 //正則表達(dá)式 NSString * pattern = @"//[[a-zA-Z0-9//u4e00-//u9fa5]+//]"; NSError *error = nil; NSRegularExPRession * re = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:&error]; if (!re) { NSLog(@"%@", [error localizedDescription]); } //通過(guò)正則表達(dá)式來(lái)匹配字符串 NSArray *resultArray = [re matchesInString:str options:0 range:NSMakeRange(0, str.length)];
6.數(shù)據(jù)準(zhǔn)備工作完成,下面開(kāi)始遍歷資源文件找到文字對(duì)應(yīng)的圖片,找到后把圖片名存入字典中,圖片在源字符串中的位置也要存入到字典中,最后把字典存入可變數(shù)組中。代碼如下:
1 //用來(lái)存放字典,字典中存儲(chǔ)的是圖片和圖片對(duì)應(yīng)的位置 2 NSMutableArray *imageArray = [NSMutableArray arrayWithCapacity:resultArray.count]; 3 4 //根據(jù)匹配范圍來(lái)用圖片進(jìn)行相應(yīng)的替換 5 for(NSTextCheckingResult *match in resultArray) { 6 //獲取數(shù)組元素中得到range 7 NSRange range = [match range]; 8 9 //獲取原字符串中對(duì)應(yīng)的值10 NSString *subStr = [str substringWithRange:range];11 12 for (int i = 0; i < face.count; i ++)13 {14 if ([face[i][@"chs"] isEqualToString:subStr])15 {16 17 //face[i][@"gif"]就是我們要加載的圖片18 //新建文字附件來(lái)存放我們的圖片19 NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];20 21 //給附件添加圖片22 textAttachment.image = [UIImage imageNamed:face[i][@"png"]];23 24 //把附件轉(zhuǎn)換成可變字符串,用于替換掉源字符串中的表情文字25 NSAttributedString *imageStr = [NSAttributedString attributedStringWithAttachment:textAttachment];26 27 //把圖片和圖片對(duì)應(yīng)的位置存入字典中28 NSMutableDictionary *imageDic = [NSMutableDictionary dictionaryWithCapacity:2];29 [imageDic setObject:imageStr forKey:@"image"];30 [imageDic setObject:[NSValue valueWithRange:range] forKey:@"range"];31 32 //把字典存入數(shù)組中33 [imageArray addObject:imageDic];34 35 }36 }37 }
7.轉(zhuǎn)換完成,我們需要對(duì)attributeString進(jìn)行替換,替換的時(shí)候要從后往前替換,弱從前往后替換,會(huì)造成range和圖片要放的位置不匹配的問(wèn)題。替換代碼如下:
1 //從后往前替換2 for (int i = imageArray.count -1; i >= 0; i--)3 {4 NSRange range;5 [imageArray[i][@"range"] getValue:&range];6 //進(jìn)行替換7 [attributeString replaceCharactersInRange:range withAttributedString:imageArray[i][@"image"]];8 9 }
8.把替換好的可變屬性字符串賦給TextView
1 //把替換后的值賦給我們的TextView2 self.myTextView.attributedText = attributeString;
9.替換前后效果如下:

新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注