效果图:
前言:要做成上面的效果图,需要我们自定义键盘。但是上面的键盘一个view 就可以搞定,可是下面的表情或者扩展怎么处理呢,有人说用UITextview的inputView 处理,可是在使用inpuview的时候,处理表情键盘或者扩展键盘,UITextview会一直成为响应者,光标会一直存在,所以我们把辅助键盘放在 下面。
如图:
大概思路就是 点击键盘上UITextview的时候,让UITextview成为第一响应者,点击语音按钮,表情按钮,more 按钮,让UITextview取消第一响应者,然后把辅助键盘视图放置在键盘的下方。
1、 首先,我们自定义一个view,ChatBox。设置几种 键盘状态
typedef NS_ENUM(NSInteger, LXChatBoxStatus) {
LXChatBoxStatusNothing, // 默认状态
LXChatBoxStatusShowVoLXe, // 录音状态
LXChatBoxStatusShowFace, // 输入表情状态
LXChatBoxStatusShowMore, // 显示“更多”页面状态
LXChatBoxStatusShowKeyboard,// 正常键盘
LXChatBoxStatusShowVideo // 录制视频
};
@property(nonatomic,assign)LXChatBoxStatus status;
在点击按钮或者 编辑UITextview的时候设置状态:
#pragma mark---textview--代理方法---
-(void)textViewDidBeginEditing:(UITextView *)textView{
if (self.status != LXChatBoxStatusShowKeyboard) {
self.status = LXChatBoxStatusShowKeyboard;
}
[self changeFrame:ceilf([textView sizeThatFits:textView.frame.size].height)];
}
#pragma mark---Event Responds---
-(void)voiceButtonDown:(UIButton *)button{
button.selected = !button.selected;
if (button.selected) {
self.status = LXChatBoxStatusShowKeyboard;
}else{
self.status = LXChatBoxStatusShowVoLXe;
}
}
-(void)faceButtonDown:(UIButton *)button{
button.selected = !button.selected;
if (button.selected) {
self.status = LXChatBoxStatusShowFace;
}else{
self.status = LXChatBoxStatusShowKeyboard;
}
}
-(void)moreButtonDown:(UIButton *)button{
button.selected = !button.selected;
if (button.selected) {
self.status = LXChatBoxStatusShowMore;
}else{
self.status = LXChatBoxStatusShowKeyboard;
}
}
通过设置键盘状态,在设置状态里对键盘视图的隐藏做一些处理。调整高度
-(void)setStatus:(LXChatBoxStatus)status{
if (_status == status) {
return;
}
_status = status;
switch (_status) {
case LXChatBoxStatusNothing:
{
self.voiceButton.selected = YES;
self.faceView.hidden = self.moreView.hidden = YES;
[self.textView resignFirstResponder];
[UIView animateWithDuration:0.3 animations:^{
self.frame = CGRectMake(0, KScreenH - self.textView.height - 2 *BOXTEXTViewSPACE, KScreenW, self.textView.height + 2 *BOXTEXTViewSPACE);
}];
}
break;
case LXChatBoxStatusShowKeyboard:
{
self.faceView.hidden = self.moreView.hidden = YES;
self.voiceButton.selected = YES;
self.textView.hidden = NO;
self.talkButton.hidden = YES;
self.faceButton.selected= NO;
[UIView animateWithDuration:0.3 animations:^{
self.frame = CGRectMake(0, self.y, KScreenW, self.textView.height + 2 *BOXTEXTViewSPACE);
}];
[self.textView becomeFirstResponder];
}
break;
case LXChatBoxStatusShowVoLXe:
{
self.faceView.hidden = self.moreView.hidden = YES;
[self.textView resignFirstResponder];
self.voiceButton.selected = NO;
self.talkButton.hidden = NO;
self.textView.hidden = YES;
[UIView animateWithDuration:0.3 animations:^{
[self voiceResetFrame];
}];
}
break;
case LXChatBoxStatusShowFace:
{
if (self.textView.isFirstResponder) {
[self.textView resignFirstResponder];
}
self.voiceButton.selected = YES;
self.moreView.hidden = YES;
self.faceView.hidden = NO;
self.height = self.textView.height+2 *BOXTEXTViewSPACE + BOXOTHERH;
self.y = KScreenH - self.height;
self.bottomCotainer.y = self.textView.height + 2 *BOXTEXTViewSPACE;
}
break;
case LXChatBoxStatusShowMore:
{
if (self.textView.isFirstResponder) {
[self.textView resignFirstResponder];
}
self.voiceButton.selected = YES;
self.moreView.hidden = NO;
self.faceView.hidden = YES;
self.height = self.textView.height+2 *BOXTEXTViewSPACE + BOXOTHERH;
self.y = KScreenH - self.height;
self.bottomCotainer.y = self.textView.height + 2 *BOXTEXTViewSPACE;
}
default:
break;
}
if ([self.delegate respondsToSelector:@selector(changeStatusChat:)]) {
[self.delegate changeStatusChat:self.y];
}
}
2、但是,只是在状态里设置键盘高度是不够的,如果我们点击UITextview,执行顺序是这样的:
(1) -(void)keyboardWillChangeFrame:(NSNotification *)notification
(2) -(void)textViewDidBeginEditing:(UITextView *)textView
所以说,如果没有点击其他按钮(声音,表情,更多),点击了UITextview,在-(void)textViewDidBeginEditing:(UITextView *)textView
设置键盘状态是没有用的,所以要键盘通知里做处理
-(void)keyboardWillChangeFrame:(NSNotification *)notification{
//因为在 切换视图的时候,点击了表情按钮,或者更多按钮,输入框是,键盘弹出在textViewDidBeginEditing 这个方法调用之前就会调用,
// self.height = self.textView.height + 2 *BOXTEXTViewSPACE;
if (self.status == LXChatBoxStatusShowMore ||self.status == LXChatBoxStatusShowFace) {
return;
}
3、 针对键盘高度改变设置代理接口
@property(nonatomic,weak)id<LXChatBoxDelegate>delegate;
在键盘高度改变的地方设置代理(键盘状态改变得地方),(键盘Textview文字 改变的地方)(键盘通知),
if ([self.delegate respondsToSelector:@selector(changeStatusChat:)]) {
[self.delegate changeStatusChat:self.y];
}
关于 接口:@property(nonatomic,assign)BOOL isDisappear;//为了在侧滑返回的时候自定义键盘与 键盘一体
,可以参考文章:一体键盘
demo 地址:仿微信键盘