前言##
本文是在前文的基礎(chǔ)上展開的,如果對(duì)自定義UITextView不熟悉,可以參考前文:
本文詳細(xì)講解怎樣自定義無表情的鍵盤,什么是無表情的鍵盤,意思就是沒有集成表情包的鍵盤,如果需要有表情包的鍵盤,可以參考下文
自定義鍵盤系列之四自定義帶表情的鍵盤
本文效果圖

怎么自定義無表情包鍵盤###
前期準(zhǔn)備####
1、一般都是從一個(gè)輸入工具條開始,工具條包括發(fā)送按鈕 + 自定義的UITextView
2、自定義的UITextView,可以設(shè)置占位文字,前文中我已經(jīng)自定義一個(gè)LZBTextView自定義鍵盤系列之一怎樣自定義輸入文本框
自定義無表情包鍵盤功能分析####
當(dāng)我們封裝一個(gè)工具的時(shí)候一定會(huì)考慮幾個(gè)問題:
1、我們把這個(gè)工具當(dāng)做是一個(gè)黑盒子,那么整體思路應(yīng)該怎么設(shè)計(jì)?
2、API怎么設(shè)計(jì),才會(huì)讓使用者使用更加方便?
3、把復(fù)雜的邏輯盡量封裝到內(nèi)部處理?
4、內(nèi)部數(shù)據(jù)變化之后,怎么讓外界知道等。
了解了設(shè)計(jì)需要考慮的問題之后,我們還需要想一想我們這個(gè)功能的核心點(diǎn)在哪里,小編以為有以下幾點(diǎn):
A、工具條的位置怎么隨著鍵盤的彈出或者隱藏而變化?
B、計(jì)算輸入文字的高度?
C、輸入框的高度怎么隨著文字的增多而高度增加?
D、當(dāng)文字輸入到限制高度的時(shí)候,不會(huì)在增加輸入框的高度等?
自定義無表情包鍵盤功能實(shí)現(xiàn)####
我自定義的工具條通過block方式傳輸給外界數(shù)據(jù)
并且使用類方法快速創(chuàng)建
toolBarHeight:設(shè)置自定義條的高度,沒有設(shè)置為默認(rèn)值
+ (LZBKeyBoardToolBar *)showKeyBoardWithConfigToolBarHeight:(CGFloat)toolBarHeight sendTextCompletion:(void(^)(NSString *sendText))sendTextBlock
{
LZBKeyBoardToolBar *toolBar = [[LZBKeyBoardToolBar alloc]init];
toolBar.backgroundColor = LZBColorRGB(247, 248, 250);
if(toolBarHeight < kKeyboardViewToolBarHeight)
toolBarHeight = kKeyboardViewToolBarHeight;
toolBar.frame = CGRectMake(0, LZBScreenHeight - toolBarHeight, LZBScreenWidth, toolBarHeight);
toolBar.sendTextBlock = sendTextBlock;
return toolBar;
}
同時(shí)設(shè)置占位文字
- (void)setInputViewPlaceHolderText:(NSString *)placeText;
A、工具條的位置怎么隨著鍵盤的彈出或者隱藏而變化?
監(jiān)聽鍵盤UIKeyboardWillChangeFrameNotification通知,注意通知三部曲(增加、移除、實(shí)現(xiàn)方法)
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
在通知方法中實(shí)現(xiàn)工具條的y值變化
- (void)keyboardWillChangeFrame:(NSNotification *)notification
{
CGRect keyboardFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat keyboardHeight = keyboardFrame.size.height;
CGFloat keyboardAnimaitonDuration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
self.animationDuration = keyboardAnimaitonDuration;
NSInteger option = [notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
//判斷鍵盤是否出現(xiàn)
BOOL isKeyBoardHidden = LZBScreenHeight == keyboardFrame.origin.y;
CGFloat offsetMarginY = isKeyBoardHidden ? LZBScreenHeight - self.LZB_heigth :LZBScreenHeight - self.LZB_heigth - keyboardHeight;
[UIView animateKeyframesWithDuration:self.animationDuration delay:0 options:option animations:^{
self.LZB_y = offsetMarginY;
} completion:nil];
}
B、計(jì)算輸入文字的高度?
注意:我們輸入的文本內(nèi)容實(shí)際是通過textContainer顯示的,所以我們計(jì)算文字高度的時(shí)候,一定要考慮textContainer的邊距問題,詳細(xì)問題請(qǐng)點(diǎn)擊自定義鍵盤系列之一怎樣自定義輸入文本框
CGFloat margin = self.inputTextView.textContainerInset.left + self.inputTextView.textContainerInset.right;
CGFloat height = [self.inputTextView.text boundingRectWithSize:CGSizeMake(self.inputTextView.LZB_width - margin, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : self.inputTextView.font} context:nil].size.height;
C、輸入框的高度怎么隨著文字的增多而高度增加?
D、當(dāng)文字輸入到限制高度的時(shí)候,不會(huì)在增加輸入框的高度等?
通過通知監(jiān)聽文字的輸入
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChange) name:UITextViewTextDidChangeNotification object:self.inputTextView];
并在文字監(jiān)聽的方法中實(shí)現(xiàn)計(jì)算文字的高度并布局
- (void)textDidChange
{
if([self.inputTextView.text containsString:@"\n"])
{
[self sendBtnClick];
return;
}
CGFloat margin = self.inputTextView.textContainerInset.left + self.inputTextView.textContainerInset.right;
CGFloat height = [self.inputTextView.text boundingRectWithSize:CGSizeMake(self.inputTextView.LZB_width - margin, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : self.inputTextView.font} context:nil].size.height;
if(height == self.textHeight) return;
// 確保輸入框不會(huì)無限增高,控制在顯示4行
if (height > kKeyboardViewToolBar_TextView_LimitHeight) {
return;
}
self.textHeight = height;
[self setNeedsLayout];
}
在布局中,整體的工具條的y值和高度在改變,內(nèi)部的輸入框和發(fā)送按鈕也在改變(注意先后順序)
- (void)layoutSubviews
{
[super layoutSubviews];
__weak typeof(self) weakSelf = self;
//計(jì)算高度
CGFloat height = (self.textHeight + kKeyboardViewToolBar_TextView_Height)> kKeyboardViewToolBarHeight ? (self.textHeight + kKeyboardViewToolBar_TextView_Height) : kKeyboardViewToolBarHeight;
CGFloat offsetY = self.LZB_heigth - height;
//一定是整體的工具條先動(dòng)畫
[UIView animateWithDuration:self.animationDuration animations:^{
weakSelf.LZB_y += offsetY;
weakSelf.LZB_heigth = height;
}];
self.topLine.LZB_width = self.LZB_width;
self.bottomLine.LZB_width = self.LZB_width;
//設(shè)置發(fā)送按鈕的尺寸
CGSize sendButtonSize = self.sendBtn.currentImage.size;
self.sendBtn.LZB_width = sendButtonSize.width;
self.sendBtn.LZB_heigth = sendButtonSize.height;
self.sendBtn.LZB_x = self.LZB_width - sendButtonSize.width - kKeyboardViewToolBar_Horizontal_DefaultMargin;
self.inputTextView.LZB_width = self.LZB_width - sendButtonSize.width - 3 *kKeyboardViewToolBar_Horizontal_DefaultMargin;
self.inputTextView.LZB_x = kKeyboardViewToolBar_Horizontal_DefaultMargin;
//子控件的動(dòng)畫
[UIView animateWithDuration:self.animationDuration animations:^{
weakSelf.inputTextView.LZB_heigth = weakSelf.LZB_heigth - 2 *kKeyboardViewToolBar_Vertical_DefaultMargin;
weakSelf.inputTextView.LZB_centerY = weakSelf.LZB_heigth * 0.5;
weakSelf.sendBtn.LZB_y = weakSelf.LZB_heigth - sendButtonSize.height -kKeyboardViewToolBar_Vertical_DefaultMargin;
weakSelf.bottomLine.LZB_y = weakSelf.LZB_heigth - weakSelf.bottomLine.LZB_heigth;
}];
[self.inputTextView setNeedsUpdateConstraints];
}
最后效果截圖

小建議###
我覺得每個(gè)公司都應(yīng)該有自己的一套鍵盤,小編在這里給大家整理出來了一套,但是可能不一定適合您的項(xiàng)目,但是依然具有參考價(jià)值,真正合適的是要自己寫的。
詳情代碼請(qǐng)直接下載demo查看:
自定義鍵盤-LZBKeyBoardView
最后贈(zèng)言###
star 是對(duì)我們程序猿最大的鼓勵(lì)