iOS 一步步封裝一個(gè)微信鍵盤

效果圖:


鍵盤.gif

前言:要做成上面的效果圖,需要我們自定義鍵盤。但是上面的鍵盤一個(gè)view 就可以搞定,可是下面的表情或者擴(kuò)展怎么處理呢,有人說用UITextview的inputView 處理,可是在使用inpuview的時(shí)候,處理表情鍵盤或者擴(kuò)展鍵盤,UITextview會(huì)一直成為響應(yīng)者,光標(biāo)會(huì)一直存在,所以我們把輔助鍵盤放在 下面。

如圖:


說明.png
大概思路就是 點(diǎn)擊鍵盤上UITextview的時(shí)候,讓UITextview成為第一響應(yīng)者,點(diǎn)擊語音按鈕,表情按鈕,more 按鈕,讓UITextview取消第一響應(yīng)者,然后把輔助鍵盤視圖放置在鍵盤的下方。
1、 首先,我們自定義一個(gè)view,ChatBox。設(shè)置幾種 鍵盤狀態(tài)
typedef NS_ENUM(NSInteger, LXChatBoxStatus) {
    LXChatBoxStatusNothing,     // 默認(rèn)狀態(tài)
    LXChatBoxStatusShowVoLXe,   // 錄音狀態(tài)
    LXChatBoxStatusShowFace,    // 輸入表情狀態(tài)
    LXChatBoxStatusShowMore,    // 顯示“更多”頁面狀態(tài)
    LXChatBoxStatusShowKeyboard,// 正常鍵盤
    LXChatBoxStatusShowVideo    // 錄制視頻
};

@property(nonatomic,assign)LXChatBoxStatus status;

在點(diǎn)擊按鈕或者 編輯UITextview的時(shí)候設(shè)置狀態(tài):
#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;
    }
}
通過設(shè)置鍵盤狀態(tài),在設(shè)置狀態(tài)里對(duì)鍵盤視圖的隱藏做一些處理。調(diào)整高度
-(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、但是,只是在狀態(tài)里設(shè)置鍵盤高度是不夠的,如果我們點(diǎn)擊UITextview,執(zhí)行順序是這樣的:

(1) -(void)keyboardWillChangeFrame:(NSNotification *)notification
(2) -(void)textViewDidBeginEditing:(UITextView *)textView

所以說,如果沒有點(diǎn)擊其他按鈕(聲音,表情,更多),點(diǎn)擊了UITextview,在-(void)textViewDidBeginEditing:(UITextView *)textView設(shè)置鍵盤狀態(tài)是沒有用的,所以要鍵盤通知里做處理
-(void)keyboardWillChangeFrame:(NSNotification *)notification{
    
   
    //因?yàn)樵?切換視圖的時(shí)候,點(diǎn)擊了表情按鈕,或者更多按鈕,輸入框是,鍵盤彈出在textViewDidBeginEditing 這個(gè)方法調(diào)用之前就會(huì)調(diào)用,
//        self.height = self.textView.height + 2 *BOXTEXTViewSPACE;
    if (self.status == LXChatBoxStatusShowMore ||self.status == LXChatBoxStatusShowFace) {
        return;
    }
3、 針對(duì)鍵盤高度改變?cè)O(shè)置代理接口
@property(nonatomic,weak)id<LXChatBoxDelegate>delegate;
在鍵盤高度改變的地方設(shè)置代理(鍵盤狀態(tài)改變得地方),(鍵盤Textview文字 改變的地方)(鍵盤通知),
 if ([self.delegate respondsToSelector:@selector(changeStatusChat:)]) {
        [self.delegate changeStatusChat:self.y];
    }

關(guān)于 接口:@property(nonatomic,assign)BOOL isDisappear;//為了在側(cè)滑返回的時(shí)候自定義鍵盤與 鍵盤一體,可以參考文章:一體鍵盤
demo 地址:仿微信鍵盤

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 2017.02.22 可以練習(xí),每當(dāng)這個(gè)時(shí)候,腦袋就犯困,我這腦袋真是神奇呀,一說讓你做事情,你就犯困,你可不要太...
    Carden閱讀 1,378評(píng)論 0 1
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,257評(píng)論 4 61
  • 文:呂一品 01 幾年前,我有過一份工作,那時(shí)新來一個(gè)叫李娟的后生。第一年就成了我們公司的熱點(diǎn),大家都在議論她。 ...
    呂一品閱讀 556評(píng)論 2 2
  • 以前上高中沒覺得滿課有什么不舒服,反而覺得很充實(shí)討厭的星期五它天經(jīng)地義。可是自從步入大學(xué),感覺好多課特別是周二周五...
    丫丫孩紙啊閱讀 414評(píng)論 2 2
  • 孩子心理教育特別重要,如果她自信,不輕易相信別人對(duì)她說的甜言蜜語,不輕易上當(dāng),就不會(huì)有這個(gè)故事。結(jié)局很感人,一位爸...
    美一天閱讀 297評(píng)論 0 0