1. 程式人生 > >IOS 自定義軟鍵盤功能,修改換行鍵為傳送鍵

IOS 自定義軟鍵盤功能,修改換行鍵為傳送鍵

IOS專案是使用混合模式開發,在開發聊天功能時;發現軟鍵盤不能像QQ、微信那樣,換行鍵不能變為傳送;網上說是因為輸入框類別導致;嘗試過以後,還是不行;然後想到用IOS native解決;

先說一下,原生APP 設定軟鍵盤換行鍵為傳送鍵:

textField.returnKeyType = UIReturnKeySend;//變為傳送按鈕

這裡說一下流程,程式碼最後貼;

1.註冊監聽軟鍵盤彈起事件

     a).獲取軟鍵盤檢視

     b).獲取換行鍵檢視,IOS中換行鍵叫做Return-Key

     c).建立UiButton,將button新增到換行鍵檢視中,建立button時 frame設定位 x=0,y=0,width=換行鍵width,height=換行鍵height

     d).允許換行鍵與使用者互動:setUserInteractionEnabled: YES

     e).註冊button TouchDown和TouchUpInside事件

     f).新增button事件響應函式

     g).新增軟鍵盤tap事件代理

2.註冊監聽軟鍵盤輸入法切換事件

    a).建立Timer定時器,不用迴圈;建立前先判斷一下定時器是否活動,如果處於活動中,先銷燬再建立,延時在100ms

    b).重複1中的步驟

    c).銷燬定時器並置為nil

3.軟鍵盤tap代理:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch

這裡說一下為什麼要做軟鍵盤tap代理,因為軟鍵盤當中很多功能鍵都會切換整個鍵盤檢視,所以要重新新增;而且不能直接給這些功能鍵不能直接設定tap事件,因為這些按鍵檢視本身是不允許與使用者互動的;如果你設定了,則按鍵不能正常輸入

    a).獲取軟鍵盤檢視

    b).判斷tap的touch的點是否在軟鍵盤的功能鍵當中

    c).如果是,則重複2當中步驟

最後,將第一部分程式碼抽離出來成為一個函式,2、3中直接呼叫即可。

程式碼部分:

1.在viewDidLoad中註冊通知:

// 鍵盤出現的通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil];
    // 鍵盤消失的通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillBeHiden:) name:UIKeyboardWillHideNotification object:nil];
    //輸入法切換
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(inputModeDidChange:) name:UITextInputCurrentInputModeDidChangeNotification object:nil];

2.註冊通知的響應函式:

- (void)keyboardWasShown:(NSNotification *)notification
{
    NSLog(@"彈起");
    [self createSendBtnInKeyBoardTimer:timer];
}
- (void)keyboardWillBeHiden:(NSNotification *)notification
{
     NSLog(@"收起");
//    self.textFiledScrollView.frame = CGRectMake(0, 64, kViewWidth, 455.5);
}

- (void) inputModeDidChange:(NSNotification*) notification {
    NSLog(@"inputModeDidChange");
    timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(createSendBtnInKeyBoardTimer:) userInfo:nil repeats:NO];
}

3.添加發送按鈕到換行鍵檢視中實現:

- (void)createSendBtnInKeyBoardTimer:(NSTimer*)timer {
    NSLog(@"create sendBtn");
    if(nil != button){
        [button removeFromSuperview];
        button = nil;
    }
    //判斷當前頁面是否為聊天介面
    UIWebView *webview = (UIWebView *)self.webView;
    NSString *hidden = [webview stringByEvaluatingJavaScriptFromString:@"document.getElementById('communicationTab') == null "];
    NSLog(@"hidden: %@", hidden);
    if(![hidden isEqualToString: @"false"]){
        return;
    }
    UIView *keyboard = [self findKeyboard];
    NSArray *arr = [keyboard subviews];
    //    UIView * impl = arr[0];
    //    NSArray *arr2 = [[[impl subviews][0] subviews][1] subviews];
    UIView *returnView = [self findKey: arr byType: @"Return-Key"];
    if(nil != returnView){
        CGRect rect = [returnView frame];
        button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, rect.size.width, rect.size.height)];
        [[button layer] setCornerRadius: 4];
        [button setBackgroundColor:[UIColor colorWithRed:20/255.0 green:106/255.0 blue:255/255.0 alpha:1]];
        [button setTitle:@"傳送"forState:UIControlStateNormal];
        [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        [returnView addSubview:button];
        //允許return按鈕事件觸發
        [returnView setUserInteractionEnabled:YES];//允許與使用者互動 
        [button addTarget:self
                   action:@selector(sendBtnDown:)
         forControlEvents:UIControlEventTouchDown];
        [button addTarget:self
                   action:@selector(sendBtnTouchUp:)
         forControlEvents:UIControlEventTouchUpInside];
        
        UITapGestureRecognizer *tapGesturRecognizer=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(imageViewTapped:)];
        //新增軟鍵盤tap事件
        tapGesturRecognizer.delegate = self;
        //這裡不會響應 因為在代理函式中已經阻止事件傳遞
        [keyboard addGestureRecognizer: tapGesturRecognizer];
        //不能給按鍵直接新增事件 因為被鍵盤檢視攔截了
//        UIView* shiftView = [self findKey: arr byType: @"Shift-Key"];
//        if(nil != shiftView){
//            [shiftView addGestureRecognizer: tapGesturRecognizer];
//        }
        
    }
    if(timer){
        [timer invalidate];
        timer = nil;
    }
}

4.軟鍵盤tap事件代理函式實現:

/**
 keyboardView tap事件代理方法
 只需獲取touch位置 去鍵盤中判斷 如果位置在指定的幾個按鍵中,就去執行一定的方法
 最後返回NO 阻止事件繼續,否則鍵盤不能輸入
 */
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
     NSLog(@"ges:UITouch");
    UIWebView *webview = (UIWebView *)self.webView;
    NSString *hidden = [webview stringByEvaluatingJavaScriptFromString:@"document.getElementById('communicationTab') == null "];
    NSLog(@"hidden: %@", hidden);
    if(![hidden isEqualToString: @"false"]){
        return NO;
    }
    UIView *keyboard = [self findKeyboard];
    
    NSArray *arr = [keyboard subviews];
    BOOL isTouchedInView = false;
    //新增功能鍵名稱 這個可以自己列印看一下
    NSArray * keyTypes = @[@"Shift-Key",
                           @"More-Key",
                           @"TenKey-Chinese-Wubihua-Alphabet-Keyplane-Switch-Key",
                           @"TenKey-Chinese-Facemark",
                           @"TenKey-Wubihua-Keyplane-Switch-Key",
                           @"TenKey-Number-To-Number-Alternative-Keyplane-Switch-Key",
                           @"TenKey-Pinyin-Keyplane-Switch-Key",
                           @"TenKey-Chinese-Number-Keyplane-Switch-Key"];
    //touchedInKeyboardViewByArrayKey 判斷touch的點是否在這些功能按鍵範圍內
    isTouchedInView = [self touchedInKeyboardViewByArrayKey:arr byTypes:keyTypes byTouch:touch];
    if(isTouchedInView){
        NSLog(@"觸控點在檢視內");
        if(timer){
            [timer invalidate];
            timer = nil;
        }
        timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(createSendBtnInKeyBoardTimer:) userInfo:nil repeats:NO];
        return NO;
    }
    return NO;
}
//不會執行到這裡來 但是最好還是寫上
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceivePress:(UIPress *)press {
     NSLog(@"ges:UIPress");
    return NO;
}

最後來幾個截圖: