iOS 一步步封装一个微信键盘

效果图:


键盘.gif

前言:要做成上面的效果图,需要我们自定义键盘。但是上面的键盘一个view 就可以搞定,可是下面的表情或者扩展怎么处理呢,有人说用UITextview的inputView 处理,可是在使用inpuview的时候,处理表情键盘或者扩展键盘,UITextview会一直成为响应者,光标会一直存在,所以我们把辅助键盘放在 下面。

如图:


iOS 一步步封装一个微信键盘_第1张图片
说明.png
大概思路就是 点击键盘上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)iddelegate;
在键盘高度改变的地方设置代理(键盘状态改变得地方),(键盘Textview文字 改变的地方)(键盘通知),
 if ([self.delegate respondsToSelector:@selector(changeStatusChat:)]) {
        [self.delegate changeStatusChat:self.y];
    }

关于 接口:@property(nonatomic,assign)BOOL isDisappear;//为了在侧滑返回的时候自定义键盘与 键盘一体,可以参考文章:一体键盘
demo 地址:仿微信键盘

你可能感兴趣的:(iOS 一步步封装一个微信键盘)