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;
}
最后来几个截图: