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

效果图:


键盘.gif

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

如图:


说明.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)id<LXChatBoxDelegate>delegate;
在键盘高度改变的地方设置代理(键盘状态改变得地方),(键盘Textview文字 改变的地方)(键盘通知),
 if ([self.delegate respondsToSelector:@selector(changeStatusChat:)]) {
        [self.delegate changeStatusChat:self.y];
    }

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 2017.02.22 可以练习,每当这个时候,脑袋就犯困,我这脑袋真是神奇呀,一说让你做事情,你就犯困,你可不要太...
    Carden阅读 1,378评论 0 1
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,255评论 4 61
  • 文:吕一品 01 几年前,我有过一份工作,那时新来一个叫李娟的后生。第一年就成了我们公司的热点,大家都在议论她。 ...
    吕一品阅读 556评论 2 2
  • 以前上高中没觉得满课有什么不舒服,反而觉得很充实讨厌的星期五它天经地义。可是自从步入大学,感觉好多课特别是周二周五...
    丫丫孩纸啊阅读 414评论 2 2
  • 孩子心理教育特别重要,如果她自信,不轻易相信别人对她说的甜言蜜语,不轻易上当,就不会有这个故事。结局很感人,一位爸...
    美一天阅读 297评论 0 0