在上一篇博客中山寨了一下新浪微博,在以後的博客中會對上一篇代碼進行優化和重用,上一篇的微博請求的文字中有一些表情沒作處理,好比帶有表情的文字是這樣的「我要[大笑],[得意]」。顯示的就是請求的字符串,那麼咱們如何把文字在本地轉換成表情呢?下面將要說一下顯示錶情的解決方案。正則表達式
要用到的知識:IOS開發中的資源文件.plist, 可變的屬性字符串,TextView和正則表達式的使用。數組
解決的總體思路:把源字符串同過正則匹配獲取到每一個表情的range, 再經過range獲取元字符串中的表情字符串,如[哈哈], 在把[哈哈] 和咱們.plist中item下的chs字段匹配,而後獲取對應的圖片名,獲取圖片後把圖片轉換成可變字符串的附件,而後作一個替換便可。先這麼大體一說,下面會詳細的講解一下。網絡
1.要想在咱們手機上顯示網絡請求的表情,首先咱們本地得有相應的資源文件,在.plist文件中又咱們想要的東西,其中存儲的東西以下所示,整個root是一個數組,數組中的item是一個字典,字典中存放的時文字到圖片名的一個映射,固然啦,圖片名和咱們本地資源的圖片名相同。截圖以下測試
2.如何從.plist文件中獲取數據呢?先經過bundle獲取資源文件的路徑,在經過文件路徑建立數組,數組中存儲的數據就是文件中的內容代碼以下:優化
//加載plist文件中的數據 NSBundle *bundle = [NSBundle mainBundle]; //尋找資源的路徑 NSString *path = [bundle pathForResource:@"emoticons" ofType:@"plist"]; //獲取plist中的數據 NSArray *face = [[NSArray alloc] initWithContentsOfFile:path];
3.生成咱們的測試字符串,最後一個不是任何表情,不作替換。spa
//咱們要顯示的字符串(模擬網路請求的字符串格式) NSString *str = @"我[圍觀]你[威武]你[嘻嘻]我[愛你]你[兔子]我[酷]你[帥]我[思考]你[錢][123456]";
4.把上面的str轉換爲可變的屬性字符串,由於咱們要用可變的屬性字符串在TextView上顯示咱們的表情圖片,轉換代碼以下:code
//建立一個可變的屬性字符串 NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:str];
5.進行正則匹配,獲取每一個表情在字符串中的範圍,下面的正則表達式會匹配[/*],因此[123567]也會被匹配上,下面咱們會作相應的處理blog
//正則匹配要替換的文字的範圍 //正則表達式 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]); } //經過正則表達式來匹配字符串 NSArray *resultArray = [re matchesInString:str options:0 range:NSMakeRange(0, str.length)];
6.數據準備工做完成,下面開始遍歷資源文件找到文字對應的圖片,找到後把圖片名存入字典中,圖片在源字符串中的位置也要存入到字典中,最後把字典存入可變數組中。代碼以下:圖片
1 //用來存放字典,字典中存儲的是圖片和圖片對應的位置 2 NSMutableArray *imageArray = [NSMutableArray arrayWithCapacity:resultArray.count]; 3 4 //根據匹配範圍來用圖片進行相應的替換 5 for(NSTextCheckingResult *match in resultArray) { 6 //獲取數組元素中獲得range 7 NSRange range = [match range]; 8 9 //獲取原字符串中對應的值 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 //新建文字附件來存放咱們的圖片 19 NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init]; 20 21 //給附件添加圖片 22 textAttachment.image = [UIImage imageNamed:face[i][@"png"]]; 23 24 //把附件轉換成可變字符串,用於替換掉源字符串中的表情文字 25 NSAttributedString *imageStr = [NSAttributedString attributedStringWithAttachment:textAttachment]; 26 27 //把圖片和圖片對應的位置存入字典中 28 NSMutableDictionary *imageDic = [NSMutableDictionary dictionaryWithCapacity:2]; 29 [imageDic setObject:imageStr forKey:@"image"]; 30 [imageDic setObject:[NSValue valueWithRange:range] forKey:@"range"]; 31 32 //把字典存入數組中 33 [imageArray addObject:imageDic]; 34 35 } 36 } 37 }
7.轉換完成,咱們須要對attributeString進行替換,替換的時候要從後往前替換,弱從前日後替換,會形成range和圖片要放的位置不匹配的問題。替換代碼以下:ip
1 //從後往前替換 2 for (int i = imageArray.count -1; i >= 0; i--) 3 { 4 NSRange range; 5 [imageArray[i][@"range"] getValue:&range]; 6 //進行替換 7 [attributeString replaceCharactersInRange:range withAttributedString:imageArray[i][@"image"]]; 8 9 }
8.把替換好的可變屬性字符串賦給TextView
1 //把替換後的值賦給咱們的TextView 2 self.myTextView.attributedText = attributeString;
9.替換先後效果以下: