99偷拍视频精品区一区二,口述久久久久久久久久久久,国产精品夫妇激情啪发布,成人永久免费网站在线观看,国产精品高清免费在线,青青草在线观看视频观看,久久久久久国产一区,天天婷婷久久18禁,日韩动漫av在线播放直播

怎么在iOS中實(shí)現(xiàn)表情鍵盤

怎么在iOS中實(shí)現(xiàn)表情鍵盤?很多新手對此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

創(chuàng)新互聯(lián)是專業(yè)的永福網(wǎng)站建設(shè)公司,永福接單;提供成都做網(wǎng)站、成都網(wǎng)站建設(shè),網(wǎng)頁設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行永福網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!

基本思路

首先,表情包的圖片是用bundle的形式組織的,用PPSticker類表征一套表情包,用PPEmoji類表征某一個(gè)表情,用一個(gè)plist作為配置文件,存儲表情包的信息。

怎么在iOS中實(shí)現(xiàn)表情鍵盤

表情的組織.jpg

PPStickerDataManager類主要負(fù)責(zé)數(shù)據(jù)部分,用單例的形式,這樣可以在初始化的時(shí)候只會讀取一次plist文件中的所有表情信息;同時(shí)我們把輸入框內(nèi)容發(fā)到服務(wù)端以及從服務(wù)端請求到的都是純文本的,比如會把 "笑死了?" 轉(zhuǎn)成 "笑死了[笑哭]" 這樣的純文本,而不是直接把表情圖片直接發(fā)到服務(wù)端,也就是說項(xiàng)目中有大量的地方會有把文本->表情的操作,所以PPStickerDataManager類也提供匹配某段純文本中的表情,并把文本替換為圖片的功能,PPStickerDataManager類的頭文件如下:

@interface PPStickerDataManager : NSObject

+ (instancetype)sharedInstance;

/// 所有的表情包
@property (nonatomic, strong, readonly) NSArray<PPSticker *> *allStickers;

/* 匹配給定attributedString中的所有emoji,如果匹配到的emoji有本地圖片的話會直接換成本地的圖片
*
* @param attributedString 可能包含表情包的attributedString
* @param font 表情圖片的對齊字體大小
*/
- (void)replaceEmojiForAttributedString:(NSMutableAttributedString *)attributedString font:(UIFont *)font;
@end

"真正的"鍵盤

真正的鍵盤也就是說調(diào)起表情鍵盤時(shí)輸入框是有光標(biāo)的,能進(jìn)行拖拽光標(biāo)、選中區(qū)域等的操作,這樣的體驗(yàn)才是與系統(tǒng)鍵盤一致的。其實(shí)系統(tǒng)已經(jīng)提供好了接口給我們直接使用,UITextView和UITextField都有的inputView和inputAccessoryView就是用來實(shí)現(xiàn)自定義鍵盤的,這兩個(gè)屬性的定義如下:

// Presented when object becomes first responder. If set to nil, reverts to following responder chain. If
// set while first responder, will not take effect until reloadInputViews is called.
@property (nullable, readwrite, strong) UIView *inputView;  
@property (nullable, readwrite, strong) UIView *inputAccessoryView;

同時(shí)系統(tǒng)鍵盤在 設(shè)置->聲音->按鍵音 選項(xiàng)打開且手機(jī)非靜音狀態(tài)下輸入是有按鍵的聲音的,這個(gè)按鍵音也是可以支持的,只要自定義鍵盤類遵循UIInputViewAudioFeedback協(xié)議,同時(shí)實(shí)現(xiàn) enableInputClicksWhenVisible方法并返回YES,這樣就可以在點(diǎn)擊表情的時(shí)候調(diào)用[[UIDevice currentDevice] playInputClick]方法發(fā)出按鍵音了,詳情請查看蘋果的官方文檔。

下面是Demo中鍵盤切換方法的實(shí)現(xiàn):

- (void)changeKeyboardTo:(PPKeyboardType)toType
{
 switch (toType) {
 case PPKeyboardTypeSystem:
  self.textView.inputView = nil; // 切換到系統(tǒng)鍵盤
  [self.textView reloadInputViews]; // 調(diào)用reloadInputViews方法會立刻進(jìn)行鍵盤的切換
  break;
 case PPKeyboardTypeSticker:  
  self.textView.inputView = self.stickerKeyboard; // 切換到自定義的表情鍵盤
  [self.textView reloadInputViews];
  break;
 default:
  break;
 }
}

去除表情的拖拽交互

在iOS11上,UITextView上的NSTextAttachment(表情)默認(rèn)可以進(jìn)行拖拽交互,但是卻導(dǎo)致拖動光標(biāo)時(shí)很容易觸發(fā)這個(gè)交互(圖示可以查看上面說到的微博國際版中的誤觸)。一番查找之后才找到一個(gè)比較隱蔽的屬性:textDragInteraction,直接設(shè)置為NO就能禁止掉NSTextAttachment的拖拽交互。

if (@available(iOS 11.0, *)) { // 只在iOS11及以上才有這個(gè)屬性
 _textView.textDragInteraction.enabled = NO;
}

與服務(wù)端的交互

我們在輸入框中輸入的內(nèi)容與服務(wù)端進(jìn)行交互的時(shí)候都是用純文本的,比如會把 "笑死了?" 轉(zhuǎn)成 "笑死了[笑哭]" 這樣的純文本發(fā)到服務(wù)端,而不是直接發(fā)表情圖片,向服務(wù)端請求內(nèi)容的時(shí)候也是傳回 "笑死了[笑哭]",然后客戶端再根據(jù)正則匹配找出表情替換成對應(yīng)的表情圖片,然后顯示到頁面上。具體過程可以看下圖:

怎么在iOS中實(shí)現(xiàn)表情鍵盤
與服務(wù)端的交互.png

也就是說,我們設(shè)置到輸入框的NSAttributedString中的每一個(gè)NSTextAttachment都有一個(gè)"隱藏的"屬性—表情的文本描述,這里對NSAttributedString進(jìn)行拓展就能實(shí)現(xiàn)。pp_setTextBackedString可以對NSAttributedString的指定range設(shè)置一個(gè)PPTextBackedString類型的屬性,而pp_plainTextForRange能拿到NSAttributedString指定range的純文本。具體實(shí)現(xiàn)如下:

@implementation NSAttributedString (PPAddition)

- (NSString *)pp_plainTextForRange:(NSRange)range
{
 if (range.location == NSNotFound || range.length == NSNotFound) {
 return nil;
 }

 NSMutableString *result = [[NSMutableString alloc] init];
 if (range.length == 0) {
 return result;
 }

 NSString *string = self.string;
 [self enumerateAttribute:PPTextBackedStringAttributeName inRange:range options:kNilOptions usingBlock:^(id value, NSRange range, BOOL *stop) {
 PPTextBackedString *backed = value;
 if (backed && backed.string) {
  [result appendString:backed.string];
 } else {
  [result appendString:[string substringWithRange:range]];
 }
 }];
 return result;
}

@end

@implementation NSMutableAttributedString (PPAddition)

- (void)pp_setTextBackedString:(PPTextBackedString *)textBackedString range:(NSRange)range
{
 if (textBackedString && ![NSNull isEqual:textBackedString]) {
 [self addAttribute:PPTextBackedStringAttributeName value:textBackedString range:range];
 } else {
 [self removeAttribute:PPTextBackedStringAttributeName range:range];
 }
}
@end

靈活的光標(biāo)

表情功能,UITextView都是用NSAttributedString進(jìn)行賦值的,并且我們底層其實(shí)還是用上面說到的純文本進(jìn)行實(shí)現(xiàn)的,那么把 [笑死] 轉(zhuǎn)成 ? 就會從4個(gè)字符變成1個(gè)字符,這里是有差值的,如果不處理的話就會出現(xiàn)上面提到的微博國際版中復(fù)制黏貼輸入框的表情會導(dǎo)致光標(biāo)位置不對,甚至莫名其妙多出前后空格的問題。為了精準(zhǔn)的定位光標(biāo),我們需要自行處理好這些問題。

這里自己繼承并實(shí)現(xiàn)了UITextView的子類PPStickerTextView,在這個(gè)類中重載復(fù)制、黏貼、剪切等操作,分別對應(yīng)的方法如下:

- (void)cut:(id)sender; // 剪切
- (void)copy:(id)sender; // 復(fù)制
- (void)paste:(id)sender; // 黏貼

下面以剪切方法舉例,看看怎么處理光標(biāo)的問題,需要注意的地方請看對應(yīng)的注釋:

- (void)cut:(id)sender
{
 // 1.從textView中拿到對應(yīng)的純文本,比如:笑死了[笑死]
 NSString *string = [self.attributedText pp_plainTextForRange:self.selectedRange];
 if (string.length) {
 // 2. 將純文本寫入到剪貼板中
 [UIPasteboard generalPasteboard].string = string;

 // 3. 記住當(dāng)前的光標(biāo)位置
 NSRange selectedRange = self.selectedRange;
 NSMutableAttributedString *attributeContent = [[NSMutableAttributedString alloc] initWithAttributedString:self.attributedText];
 // 4. 將檢測到是表情的文本替換成對應(yīng)的圖片
 [attributeContent replaceCharactersInRange:self.selectedRange withString:@""];
 self.attributedText = attributeContent;
 
 // 5. 重新設(shè)置光標(biāo)
 self.selectedRange = NSMakeRange(selectedRange.location, 0);
 }
}

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。

文章標(biāo)題:怎么在iOS中實(shí)現(xiàn)表情鍵盤
文章起源:http://www.yijiale78.com/article10/ghdhgo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT服務(wù)器托管企業(yè)網(wǎng)站制作面包屑導(dǎo)航品牌網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)