在上一篇部落格中山寨了一下新浪微博,在之後的部落格中會對上一篇程式碼進行優化和重用,上一篇的微博請求的文字中有一些表情沒做處理,比如帶有表情的文字是這樣的“我要[大笑],[得意]”。顯示的就是請求的字串,那麼我們如何把文字在本地轉換成表情呢?下面將要說一下顯示錶情的解決方案。
要用到的知識:IOS開發中的資原始檔.plist, 可變的屬性字串,TextView和正規表示式的使用。
解決的整體思路:把源字串同過正則匹配獲取到每個表情的range, 再通過range獲取元字串中的表情字串,如[哈哈], 在把[哈哈] 和我們.plist中item下的chs欄位匹配,然後獲取對應的圖片名,獲取圖片後把圖片轉換成可變字串的附件,然後做一個替換即可。先這麼大致一說,下面會詳細的講解一下。
1.要想在我們手機上顯示網路請求的表情,首先我們本地得有相應的資原始檔,在.plist檔案中又我們想要的東西,其中儲存的東西如下所示,整個root是一個陣列,陣列中的item是一個字典,字典中存放的時文字到圖片名的一個對映,當然啦,圖片名和我們本地資源的圖片名相同。截圖如下
2.如何從.plist檔案中獲取資料呢?先通過bundle獲取資原始檔的路徑,在通過檔案路徑建立陣列,陣列中儲存的資料就是檔案中的內容程式碼如下:
1 2 3 4 5 6 |
//載入plist檔案中的資料 NSBundle *bundle = [NSBundle mainBundle]; //尋找資源的路徑 NSString *path = [bundle pathForResource:@"emoticons" ofType:@"plist"]; //獲取plist中的資料 NSArray *face = [[NSArray alloc] initWithContentsOfFile:path]; |
3.生成我們的測試字串,最後一個不是任何表情,不做替換。
1 2 |
//我們要顯示的字串(模擬網路請求的字串格式) NSString *str = @"我[圍觀]你[威武]你[嘻嘻]我[愛你]你[兔子]我[酷]你[帥]我[思考]你[錢][123456]"; |
4.把上面的str轉換為可變的屬性字串,因為我們要用可變的屬性字串在TextView上顯示我們的表情圖片,轉換程式碼如下:
1 2 |
//建立一個可變的屬性字串 NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:str]; |
5.進行正則匹配,獲取每個表情在字串中的範圍,下面的正規表示式會匹配[/*],所以[123567]也會被匹配上,下面我們會做相應的處理
1 2 3 4 5 6 7 8 9 10 11 12 |
//正則匹配要替換的文字的範圍 //正規表示式 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 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
//用來存放字典,字典中儲存的是圖片和圖片對應的位置 NSMutableArray *imageArray = [NSMutableArray arrayWithCapacity:resultArray.count]; //根據匹配範圍來用圖片進行相應的替換 for(NSTextCheckingResult *match in resultArray) { //獲取陣列元素中得到range NSRange range = [match range]; //獲取原字串中對應的值 NSString *subStr = [str substringWithRange:range]; for (int i = 0; i ) { if ([face[i][@"chs"] isEqualToString:subStr]) { //face[i][@"gif"]就是我們要載入的圖片 //新建文字附件來存放我們的圖片 NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init]; //給附件新增圖片 textAttachment.image = [UIImage imageNamed:face[i][@"png"]]; //把附件轉換成可變字串,用於替換掉源字串中的表情文字 NSAttributedString *imageStr = [NSAttributedString attributedStringWithAttachment:textAttachment]; //把圖片和圖片對應的位置存入字典中 NSMutableDictionary *imageDic = [NSMutableDictionary dictionaryWithCapacity:2]; [imageDic setObject:imageStr forKey:@"image"]; [imageDic setObject:[NSValue valueWithRange:range] forKey:@"range"]; //把字典存入陣列中 [imageArray addObject:imageDic]; } } } |
7.轉換完成,我們需要對attributeString進行替換,替換的時候要從後往前替換,弱從前往後替換,會造成range和圖片要放的位置不匹配的問題。替換程式碼如下:
1 2 3 4 5 6 7 8 9 |
//從後往前替換 for (int i = imageArray.count -1; i >= 0; i--) { NSRange range; [imageArray[i][@"range"] getValue:&range]; //進行替換 [attributeString replaceCharactersInRange:range withAttributedString:imageArray[i][@"image"]]; } |
8.把替換好的可變屬性字串賦給TextView
1 2 |
//把替換後的值賦給我們的TextView self.myTextView.attributedText = attributeString; |
9.替換前後效果如下:
打賞支援我寫出更多好文章,謝謝!
打賞作者
打賞支援我寫出更多好文章,謝謝!