當UITextFiled和UITextView這種文本輸入類控件成爲第一響應者時,彈出的鍵盤由他們的一個UIView類的inputView屬性來控制,當inputView爲nil時會彈出系統的鍵盤,想要彈出自定義的鍵盤,將咱們自定義的UIView對象給inputView屬性賦值便可。表情鍵盤重點在於排列各個表情和刪除鍵,以及表情鍵盤上的各類回調設置;html
下面爲鍵盤預覽圖,兼容了豎屏各版本適配,橫屏沒有兼顧。橫屏適配參見這篇博客iOS之自定義表情鍵盤正則表達式
圖1爲6的經常使用表情,圖2爲6的所有表情,圖3爲5的所有表情,表情個數統一爲7列3排,根據屏幕不一樣修改間距以及鍵盤高度;數組
下面爲項目結構圖:採用MVC模式,View層提供表情鍵盤以及自定義的UITextView。Model層提供表情數據。我爲了簡單就直接把聊天工具欄經過storyboard拖到了VC上,這裏應該再封裝一個toolView的;ide
一、首先來弄好數據層FaceManager,具備一個單例方法、聲明瞭三個數組屬性來存放不一樣的表情;表情圖片由Face文件夾來提供;工具
AllFaces經過我一個名爲「emoticons」的plist文件來獲取,裏面存放的是一個個表情字典,對應着Face中的圖片名和圖片文字描述;fetch
RecentlyFaces是最近使用過的圖片,從本地獲取;BigFaces是用來擴展其餘大型以及動態效果表情的,沒有實現atom
1 @interface FacesManager : NSObject 2 3 @property (nonatomic, strong, readonly)NSArray * RecentlyFaces; 4 @property (nonatomic, strong, readonly)NSArray * AllFaces; 5 @property (nonatomic, strong, readonly)NSArray * BigFaces; 6 7 + (instancetype)share; 8 - (void)fetchRecentlyFaces; 9 @end 10 11 #import "FacesManager.h" 12 13 @implementation FacesManager 14 15 +(instancetype)share 16 { 17 static FacesManager * m = nil; 18 static dispatch_once_t onceToken; 19 dispatch_once(&onceToken, ^{ 20 m = [[FacesManager alloc] init]; 21 }); 22 return m ; 23 } 24 25 - (instancetype)init 26 { 27 self = [super init]; 28 if (self) { 29 [self fetchAllFaces]; 30 [self fetchBigFaces]; 31 } 32 return self; 33 } 34 35 - (void)fetchAllFaces 36 { 37 NSString * path = [[NSBundle mainBundle] pathForResource:@"emoticons" ofType:@"plist"]; 38 NSArray * arrFace = [NSArray arrayWithContentsOfFile:path]; 39 _AllFaces = arrFace; 40 } 41 42 - (void)fetchRecentlyFaces 43 { 44 NSUserDefaults * defauls = [NSUserDefaults standardUserDefaults]; 45 NSArray * arrFace = [defauls objectForKey:@"RecentlyFaces"]; 46 _RecentlyFaces = arrFace; 47 } 48 49 - (void)fetchBigFaces 50 { 51 52 } 53 54 @end
二、數據層弄好後,實現關鍵的FaceKeyBoardView;首先在這個view上咱們須要向外發送:點擊每一個表情、發送鍵、刪除鍵的事件,因此須要提供三個向外的回調接口:點擊表情的回調、點擊刪除的回調、點擊發送的回調;而後再分析視圖結構,首先view上部貼了一個ScrollView用來滑動顯示每一頁表情、一個稍微靠下的的pageController用於顯示當前頁數、以及底部的toolBar;spa
FaceKeyBoardView.h3d
define了幾個須要用到的參數。設置了三個回調接口;代理
1 #import <UIKit/UIKit.h> 2 #define GrayColor [UIColor colorWithRed:231 / 255.0 green:231 / 255.0 blue:231 / 255.0 alpha:1] 3 #define ScreenWidth [UIScreen mainScreen].bounds.size.width 4 #define ScreenHeight [UIScreen mainScreen].bounds.size.height 5 #define ToolBarHeight 40 6 7 typedef void (^FaceKeyBoardBlock)(NSString * faceName,NSInteger faceTag); 8 typedef void (^FaceKeyBoardSendBlock)(void); 9 typedef void (^FaceKeyBoardDeleteBlock)(void); 10 11 @interface FaceKeyBoardView : UIView 12 13 - (void)setFaceKeyBoardBlock:(FaceKeyBoardBlock)block; 14 - (void)setFaceKeyBoardSendBlock:(FaceKeyBoardSendBlock)block; 15 - (void)setFaceKeyBoardDeleteBlock:(FaceKeyBoardDeleteBlock)block; 16 @end
FaceKeyBoardView.m:
用到的屬性:
1 @interface FaceKeyBoardView ()<UIScrollViewDelegate> 2 3 { 4 CGFloat _FKBViewH; 5 } 6 7 @property (nonatomic, strong)NSArray * arrFace; 8 @property (nonatomic, strong)UIScrollView * scFace; 9 @property (nonatomic, strong)FaceKeyBoardBlock block; 10 @property (nonatomic, strong)FaceKeyBoardSendBlock sendBlock; 11 @property (nonatomic, strong)FaceKeyBoardDeleteBlock deleteBlock; 12 @property (nonatomic, strong)UIToolbar * toolBar; 13 @property (nonatomic, strong)UIPageControl * pageC; 14 15 @property (nonatomic, strong)FacesManager * FManager; 16 17 @end
a、首先來重寫view的init方法,在這裏面設定好view的frame以及設定view的子控件。因爲屏幕尺寸不一樣,因此表情豎直方向間距不一樣,就會影響到表情鍵盤的高度,因此frame是動態計算出來的;而後再loadview方法中初始化facemanager用來提供數據,以及得到所有表情和設置toolBar;
1 - (instancetype)init 2 { 3 self = [super init]; 4 if (self) { 5 [self setViewFrame]; 6 [self loadKeyBoardView]; 7 } 8 return self; 9 } 10 11 - (void)setViewFrame 12 { 13 CGFloat marginY = (ScreenWidth - 7 * 30) / (7 + 1); 14 CGFloat scViewH = 3 * (30 + marginY) + marginY*2 + 10; 15 _FKBViewH = scViewH + ToolBarHeight; 16 self.frame = CGRectMake(0, ScreenHeight - _FKBViewH, ScreenWidth, _FKBViewH); 17 } 18 19 - (void)loadKeyBoardView 20 { 21 //初始化manager 22 self.FManager = [FacesManager share]; 23 //獲取數據 24 [self fetchAllFaces]; 25 //設置toolBar 26 [self setToolBar]; 27 }
b、設置了三個方法來獲取不一樣的表情數據用於顯示不一樣的表情鍵盤;第一次時默認執行fetchAllFaces;
1 - (void)fetchRecentlyFaces 2 { 3 //更新manager 4 [self.FManager fetchRecentlyFaces]; 5 self.arrFace = self.FManager.RecentlyFaces; 6 [self setFaceFrame]; 7 } 8 9 - (void)fetchAllFaces 10 { 11 self.arrFace = self.FManager.AllFaces; 12 //設置表情scrollView 13 [self setFaceFrame]; 14 } 15 16 - (void)fetchBigFaces 17 { 18 self.arrFace = nil; 19 [self setFaceFrame]; 20 }
c、在setFaceFrame方法中設置scrollView以及pageController;我經過表情數量來循環設置每一個表情按鈕的位置,固定了7列三行,根據屏幕設置不一樣的間距,在每一頁的右下角設置刪除按鈕。根據頁數來設置scrollView的內容寬度以及pageController的頁數;
1 - (void)setFaceFrame 2 { 3 //列數 4 NSInteger colFaces = 7; 5 //行數 6 NSInteger rowFaces = 3; 7 //設置face按鈕frame 8 CGFloat FaceW = 30; 9 CGFloat FaceH = 30; 10 CGFloat marginX = (ScreenWidth - colFaces * FaceW) / (colFaces + 1); 11 CGFloat marginY = marginX; 12 NSLog(@"%lf",marginX); 13 14 //表情數量 15 NSInteger FaceCount = self.arrFace.count; 16 //每頁表情數和scrollView頁數; 17 NSInteger PageFaceCount = colFaces * rowFaces ; 18 NSInteger SCPages = FaceCount / PageFaceCount + 1; 19 20 CGFloat scViewH = rowFaces * (FaceH + marginY) + marginY*2 + 10; 21 //初始化scrollView 22 self.scFace = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, scViewH)]; 23 self.scFace.contentSize = CGSizeMake(ScreenWidth * SCPages, scViewH); 24 self.scFace.pagingEnabled = YES; 25 self.scFace.bounces = NO; 26 self.scFace.delegate = self; 27 [self addSubview:self.scFace]; 28 //初始化貼在sc上的view 29 UIView * BtnView = [[UIView alloc] init]; 30 BtnView.frame = CGRectMake(0, 0, ScreenWidth * SCPages, scViewH); 31 [BtnView setBackgroundColor:GrayColor]; 32 [self.scFace addSubview:BtnView]; 33 34 for (NSInteger i = 0; i < FaceCount + SCPages; i ++) 35 { 36 //當前頁數 37 NSInteger currentPage = i / PageFaceCount; 38 //當前行 39 NSInteger rowIndex = i / colFaces - (currentPage * rowFaces); 40 //當前列 41 NSInteger colIndex = i % colFaces; 42 43 //viewW * currentPage換頁 44 CGFloat btnX = marginX + colIndex * (FaceW + marginX) + ScreenWidth * currentPage; 45 CGFloat btnY = rowIndex * (marginY + FaceH) + marginY; 46 if ((i - (currentPage + 1) * (PageFaceCount - 1) == currentPage || i == FaceCount + SCPages - 1) && self.arrFace) 47 { 48 //建立刪除按鈕 49 CGFloat btnDelteX = (currentPage + 1) * ScreenWidth - (marginX + FaceW); 50 CGFloat btnDelteY = 2 * (FaceH + marginY) +marginY; 51 52 UIButton * btnDelte = [UIButton buttonWithType:UIButtonTypeSystem]; 53 btnDelte.frame = CGRectMake(btnDelteX, btnDelteY, FaceW, FaceH); 54 [btnDelte setBackgroundImage:[UIImage imageNamed:@"icon_delete-2"] forState:UIControlStateNormal]; 55 [btnDelte setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 56 btnDelte.titleLabel.font = [UIFont boldSystemFontOfSize:15]; 57 58 [btnDelte addTarget:self action:@selector(tapDeleteBtn) forControlEvents:UIControlEventTouchUpInside]; 59 60 [BtnView addSubview:btnDelte]; 61 } 62 else 63 { 64 //建立face按鈕 65 UIButton * btn = [[UIButton alloc] init]; 66 btn.frame = CGRectMake(btnX , btnY, FaceW, FaceH); 67 //tga 68 btn.tag = i - currentPage; 69 //按鈕回調; 70 [btn addTarget:self action:@selector(tapFaceBtnWithButton:) forControlEvents:UIControlEventTouchUpInside]; 71 NSString * strIMG = self.arrFace[i - currentPage][@"png"]; 72 [btn setImage:[UIImage imageNamed:strIMG] forState:UIControlStateNormal]; 73 [BtnView addSubview:btn]; 74 } 75 } 76 77 //建立pageController 78 CGFloat pageH = 10; 79 CGFloat pageW = ScreenWidth; 80 CGFloat pageX = 0; 81 CGFloat pageY = scViewH - pageH - marginY; 82 self.pageC = [[UIPageControl alloc] initWithFrame:CGRectMake(pageX, pageY, pageW, pageH)]; 83 self.pageC.numberOfPages = SCPages; 84 self.pageC.currentPage = 0; 85 self.pageC.pageIndicatorTintColor = [UIColor lightGrayColor]; 86 self.pageC.currentPageIndicatorTintColor = [UIColor grayColor]; 87 [self addSubview:self.pageC]; 88 }
b、還須要把c中的各類點擊事件和scrollView的代理事件實現
點擊表情的事件中我執行了2個操做:一、將點擊的表情存到本地經常使用表情數組中,邏輯爲,若是數組中已有這個表情,就將此表情移到最前面,沒有就將表情插入到數組第一位。這裏我想着數據量不是很大就使用了Preference來存放本地;二、將表情的文字描述和表情按鈕的tga經過block傳出去;
當scrollView翻動時,讓pageController的當前頁數跟着變化;點擊刪除發送回調;
1 //點擊表情 2 - (void)tapFaceBtnWithButton:(UIButton *)button 3 { 4 //將表情存儲爲經常使用表情 5 NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; 6 NSMutableArray * arrFaces = (NSMutableArray *)[defaults objectForKey:@"RecentlyFaces"]; 7 8 if (!arrFaces) 9 { 10 arrFaces = [NSMutableArray array]; 11 NSDictionary * dicFace = @{@"png":self.arrFace[button.tag][@"png"],@"faceTag":@(button.tag),@"chs":self.arrFace[button.tag][@"chs"]}; 12 [arrFaces addObject:dicFace]; 13 [defaults setObject:arrFaces forKey:@"RecentlyFaces"]; 14 [defaults synchronize]; 15 } 16 //NSLog(@"%p",arrFaces); 17 else 18 { 19 //須要新建一個可變數組,否則修改數組會報錯。 20 NSMutableArray * arrM = [NSMutableArray arrayWithArray:arrFaces]; 21 BOOL isHaveSameFace = NO; 22 for (NSDictionary * dic in arrFaces) 23 { 24 //NSLog(@"%ld--%ld",button.tag,[dic[@"faceTag"] integerValue]); 25 NSString * strFace = self.arrFace[button.tag][@"chs"]; 26 NSString * strFaceDic = dic[@"chs"]; 27 if ([strFace isEqualToString:strFaceDic]) 28 { 29 [arrM removeObject:dic]; 30 NSLog(@"%@",dic); 31 //後添加的排在前面; 32 [arrM insertObject:dic atIndex:0]; 33 isHaveSameFace = YES; 34 } 35 } 36 if (!isHaveSameFace) 37 { 38 NSDictionary * dicFace = @{@"png":self.arrFace[button.tag][@"png"],@"faceTag":@(button.tag),@"chs":self.arrFace[button.tag][@"chs"]}; 39 [arrM insertObject:dicFace atIndex:0]; 40 } 41 [defaults setObject:arrM forKey:@"RecentlyFaces"]; 42 [defaults synchronize]; 43 } 44 //block傳值 45 self.block(self.arrFace[button.tag][@"chs"],button.tag); 46 } 47 48 //點擊刪除 49 - (void)tapDeleteBtn 50 { 51 self.deleteBlock(); 52 } 53 54 -(void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset 55 { 56 self.pageC.currentPage = targetContentOffset->x / ScreenWidth; 57 }
d、設置toolBar、而後將各個按鈕的點擊事件實現:
1 - (void)setToolBar 2 { 3 self.toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, self.scFace.frame.size.height, ScreenWidth, ToolBarHeight)]; 4 self.toolBar.backgroundColor = GrayColor; 5 6 [self addSubview:self.toolBar]; 7 UIBarButtonItem * spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; 8 UIBarButtonItem * recentlyFaceItem = [[UIBarButtonItem alloc] initWithTitle:@"最近表情" style:UIBarButtonItemStylePlain target:self action:@selector(tapRecentlyFaceBtn)]; 9 UIBarButtonItem * normalFaceItem = [[UIBarButtonItem alloc] initWithTitle:@"普通" style:UIBarButtonItemStylePlain target:self action:@selector(tapNormalFaceBtn)]; 10 UIBarButtonItem * bigFaceItem = [[UIBarButtonItem alloc] initWithTitle:@"大表情" style:UIBarButtonItemStylePlain target:self action:@selector(tapBigFaceBtn)]; 11 UIBarButtonItem * sendItem = [[UIBarButtonItem alloc] initWithTitle:@"發送" style:UIBarButtonItemStylePlain target:self action:@selector(tapSendBtn)]; 12 13 [self.toolBar setItems:[NSArray arrayWithObjects:recentlyFaceItem,spaceItem,normalFaceItem,spaceItem,bigFaceItem,spaceItem,sendItem, nil]]; 14 } 15 16 17 //點擊ToolBar上的按鈕回調 18 - (void)tapRecentlyFaceBtn 19 { 20 [self fetchRecentlyFaces]; 21 } 22 - (void)tapSendBtn 23 { 24 self.sendBlock(); 25 } 26 - (void)tapBigFaceBtn{ 27 [self fetchBigFaces]; 28 } 29 - (void)tapNormalFaceBtn 30 { 31 [self fetchAllFaces]; 32 }
e、還要實現三個設置回調接口的方法、此時faceKeyBoardView中的方法都實現了;
1 //點擊表情接口 2 - (void)setFaceKeyBoardBlock:(FaceKeyBoardBlock)block 3 { 4 self.block = block; 5 } 6 //發送接口 7 -(void)setFaceKeyBoardSendBlock:(FaceKeyBoardSendBlock)block 8 { 9 self.sendBlock = block; 10 } 11 //刪除接口 12 -(void)setFaceKeyBoardDeleteBlock:(FaceKeyBoardDeleteBlock)block 13 { 14 self.deleteBlock = block; 15 }
三、自定義一個UITextView、也可使用UITextFiledView
.h:具備一個發送回調以及切換鍵盤狀態的方法:
1 #import "XQGTextView.h" 2 #import "FaceKeyBoardView.h" 3 4 @interface XQGTextView () 5 6 @property (nonatomic, strong)FaceKeyBoardView * viewFaceKB; 7 @property (nonatomic, strong)SendBlock block; 8 @end
.m:實現方法以及初始化表情鍵盤,在faceKeyBoard發送回調和刪除回調中實現須要作的事;
1 @implementation XQGTextView 2 3 - (instancetype)initWithFrame:(CGRect)frame 4 { 5 self = [super initWithFrame:frame]; 6 if (self) { 7 [self loadFaceKeyBoardView]; 8 } 9 return self; 10 } 11 12 - (void)awakeFromNib 13 { 14 [self loadFaceKeyBoardView]; 15 } 16 17 - (void)loadFaceKeyBoardView 18 { 19 self.viewFaceKB = [[FaceKeyBoardView alloc] init]; 20 21 __weak __block XQGTextView * copy_self = self; 22 23 [self.viewFaceKB setFaceKeyBoardBlock:^(NSString *faceName, NSInteger faceTag) { 24 copy_self.text = [copy_self.text stringByAppendingString:faceName]; 25 }]; 26 27 [self.viewFaceKB setFaceKeyBoardSendBlock:^{ 28 copy_self.block(); 29 //清空textview 30 copy_self.text = nil; 31 }]; 32 [self.viewFaceKB setFaceKeyBoardDeleteBlock:^{ 33 NSMutableString * string = [[NSMutableString alloc] initWithString:copy_self.text]; 34 [string deleteCharactersInRange:NSMakeRange(copy_self.text.length - 1, 1)]; 35 copy_self.text = string; 36 }]; 37 } 38 39 -(void)changeKeyBoard 40 { 41 if (self.inputView != nil) 42 { 43 self.inputView = nil; 44 [self reloadInputViews]; 45 } 46 else 47 { 48 self.inputView = self.viewFaceKB; 49 [self reloadInputViews]; 50 } 51 } 52 53 - (void)setFaceKeyBoard 54 { 55 self.inputView = self.viewFaceKB; 56 } 57 58 - (void)setSendBlock:(SendBlock)block 59 { 60 self.block = block; 61 } 62 63 @end
四、在VC中進行操做:
a、在storyBoard中構建聊天工具欄:將textView綁定爲我自定義的textView;
b、在發送回調中進行發送消息,利用正則表達式解析出表情發送圖文混排的消息;以及聊天工具欄跟隨鍵盤高度變化而變化的設置等;點擊表情按鈕彈出表情鍵盤,鍵盤切換;代碼中都有詳細描述;
.m:
1 #import "MainViewController.h" 2 #import "XQGTextView.h" 3 4 @interface MainViewController ()<UITextViewDelegate> 5 6 @property (weak, nonatomic) IBOutlet XQGTextView *viewText; 7 @property (weak, nonatomic) IBOutlet UIView *viewChatToolBar; 8 @property (weak, nonatomic) IBOutlet UILabel *lalText; 9 10 @end 11 12 @implementation MainViewController 13 14 - (void)viewDidLoad { 15 [super viewDidLoad]; 16 //清空經常使用表情 17 // NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; 18 // NSMutableArray * arrFaces = [defaults objectForKey:@"RecentlyFaces"]; 19 // arrFaces = nil; 20 // [defaults setObject:arrFaces forKey:@"RecentlyFaces"]; 21 22 self.viewText.delegate = self; 23 //發送回調 24 [self.viewText setSendBlock:^{ 25 [self sendPictureAndText]; 26 }]; 27 //監聽鍵盤彈出的通知 28 NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 29 [center addObserver:self selector:@selector(KeyBoardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil]; 30 } 31 32 //發送圖文 33 - (void)sendPictureAndText 34 { 35 //正則表達式取出表情 36 NSString * str = self.viewText.text; 37 NSMutableAttributedString * strAtt = [[NSMutableAttributedString alloc] initWithString:str]; 38 //建立匹配正則表達式類型描述模板 39 NSString * pattern = @"\\[[a-zA-Z0-9\\u4e00-\\u9fa5]+\\]"; 40 //依據正則表達式建立匹配對象 41 NSError * error = nil; 42 //CaseInsensitive 43 NSRegularExpression * regular = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:&error]; 44 if (regular == nil) 45 { 46 NSLog(@"正則建立失敗"); 47 NSLog(@"%@",error.localizedDescription); 48 return; 49 } 50 //把搜索出來的結果存到數組中 51 NSArray * result = [regular matchesInString:strAtt.string options:NSMatchingReportCompletion range:NSMakeRange(0, strAtt.string.length)]; 52 53 NSString * path = [[NSBundle mainBundle] pathForResource:@"emoticons.plist" ofType:nil]; 54 NSArray * arrPlist = [NSArray arrayWithContentsOfFile:path]; 55 56 for (NSInteger i = result.count - 1; i >= 0; i--) 57 { 58 NSTextCheckingResult * r = result[i]; 59 //NSLog(@"%@",NSStringFromRange(r.range)); 60 NSString * imageStr = [strAtt.string substringWithRange:r.range]; 61 //NSLog(@"%@",imageStr); 62 63 for (NSDictionary * dic in arrPlist) 64 { 65 if ([dic[@"chs"] isEqualToString:imageStr]) 66 { 67 NSTextAttachment * textAtt = [[NSTextAttachment alloc] init]; 68 textAtt.image = [UIImage imageNamed:dic[@"png"]]; 69 NSAttributedString * strImage = [NSAttributedString attributedStringWithAttachment:textAtt]; 70 [strAtt replaceCharactersInRange:r.range withAttributedString:strImage]; 71 } 72 } 73 } 74 self.lalText.attributedText = strAtt; 75 } 76 77 //監聽鍵盤彈出的方法 78 -(void)KeyBoardWillChangeFrame: (NSNotification *)noteInfo 79 { 80 //獲取鍵盤的Y值 81 CGRect keySize = [noteInfo.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; 82 CGFloat keyY = keySize.origin.y; 83 //讓view跟隨鍵盤移動 84 CGFloat viewY = keyY - self.view.bounds.size.height; 85 //讓view變化和鍵盤變化一致 86 self.view.transform = CGAffineTransformMakeTranslation(0, viewY); 87 } 88 89 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 90 { 91 UITouch * touch = [touches anyObject]; 92 if ([touch.view isEqual:self.view]) { 93 [self.view endEditing:YES]; 94 } 95 } 96 //監控編輯結束狀態 97 -(void)textViewDidEndEditing:(UITextView *)textView 98 { 99 self.viewText.inputView = nil; 100 } 101 102 103 - (IBAction)tapVoice:(UIButton *)sender { 104 NSLog(@"切換語音"); 105 } 106 107 - (IBAction)tapFace:(UIButton *)sender 108 { 109 //若是還沒彈出鍵盤就直接彈出表情鍵盤;彈出了就改變鍵盤樣式 110 if (self.viewText.isFirstResponder) 111 { 112 [self.viewText changeKeyBoard]; 113 } 114 else 115 { 116 [self.viewText setFaceKeyBoard]; 117 [self.viewText becomeFirstResponder]; 118 } 119 } 120 121 - (IBAction)tapMoreFunction:(UIButton *)sender { 122 NSLog(@"更多功能"); 123 } 124 125 126 @end
這樣,自定義表情鍵盤就實現了,聊天工具欄還須要進行進一步的封裝;