以html的button标签为例,避免系统自动适配input键盘升降的偏移。
原理:html加载完成后在onload中把所有输入框信息告诉原生,原生把所有输入框用原生代码写成一样的,add到WKScrollow上,然后按原生的正常升降方法。
效果:
webview使用原生键盘升降
下面是实现代码:
h5
H5向Native通信
h5与原生交互之原生代码webviewController
@property (nonatomic ,retain)NSMutableDictionary *nativeTextFiledMutableDic;
- (void)userContentController:(nonnull WKUserContentController *)userContentController didReceiveScriptMessage:(nonnull WKScriptMessage *)message {
NSLog(@"%@",message.body);
NSLog(@"%@",message.frameInfo);
NSLog(@"%@",message.name);
if([message.name isEqualToString:@"createNativeTextFiled"]){
//创建原生输入框加载到WKScrollView上
NSArray *arr = message.body;
_nativeTextFiledMutableDic = [[NSMutableDictionary alloc] initWithCapacity:arr.count];
for (NSDictionary *dic in arr) {
float top = [dic[@"top"] floatValue];
float left = [dic[@"left"] floatValue];
float height = [dic[@"height"] floatValue];
float width = [dic[@"width"] floatValue];
NSString *text = [dic[@"text"] stringValue];
UIView *wkScrollView = _myWKWebView.subviews[0];//WKScrollView
YYYTextField *nativeTextField = [[YYYTextField alloc] init];
nativeTextField.frame =CGRectMake(left, top, width, height);
nativeTextField.backgroundColor = [UIColor redColor];
nativeTextField.hidden = NO;
nativeTextField.webView = _myWKWebView;
nativeTextField.text = text;
nativeTextField.idStr = [dic[@"id"] stringValue];
[wkScrollView addSubview:nativeTextField];
[nativeTextField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
[nativeTextField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventValueChanged];
[_nativeTextFiledMutableDic setObject:nativeTextField forKey:[dic[@"id"] stringValue]];
}
NSLog(@"");
} else if([message.name isEqualToString:@"useNativeTextFiled"]){
//这个方法不是每次都走 点到后面的h5标签后 调起对应原生控件
//h5标签加上disabled="disabled"就不会走到这里了
NSDictionary *dic = message.body;
NSString *textId = [dic[@"id"] stringValue];
UITextField *filed = [_nativeTextFiledMutableDic objectForKey:textId];
[filed becomeFirstResponder];
}
}
- (void)textFieldDidChange:(YYYTextField *)textField; {
//改变文字同步到h5输入框或button文字
NSString *javaScriptStr = [NSString stringWithFormat:@"changeTextById('%@','%@');",textField.idStr,textField.text];
[_myWKWebView evaluateJavaScript:javaScriptStr completionHandler:^(NSString *str , NSError * _Nullable error) {
NSLog(@"");
}];
}
YYYTextField
#import
NS_ASSUME_NONNULL_BEGIN
@interface YYYTextField : UITextField
@property(nonatomic,weak)WKWebView *webView;
@property(nonatomic,retain)NSString *idStr;
@property(nonatomic,assign)double keyBoardHeight;
- (double)getKeyBoardHeight;
@end
NS_ASSUME_NONNULL_END
#import "YYYTextField.h"
#import "SSSPublicKeyBoardMoveUpAndDown.h"
@implementation YYYTextField
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//使用自己的升降 打开这行
self.delegate = self;
self.inputAccessoryView=nil;
self.clearButtonMode = UITextFieldViewModeWhileEditing;
//使用自己的升降 打开这行
//获取系统键盘高度
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeTextFieldFrame:) name:UIKeyboardWillShowNotification object:nil];
self.textColor = [UIColor blackColor];
}
return self;
}
//- (UIView *)inputView{
// //这里模拟返回当前输入框的自定义键盘
// //使用默认键盘可以注掉本方法
// UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 350)];
// view.backgroundColor = [UIColor redColor];
// return view;
//
//}
- (UIView *)inputAccessoryView{
//textField加到wkscrollow时,解决键盘工具栏时有时无的问题
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 0.01)];
view.backgroundColor = [UIColor redColor];
return view;
}
- (void)changeTextFieldFrame:(NSNotification *)noti
{
//获取系统键盘高度
NSDictionary *userInfo = noti.userInfo;
CGRect r = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
NSLog(@"打印一下%f",r.size.height);
_keyBoardHeight = r.size.height;
//
//防止第一次点击后先升键盘,后走这个方法,导致键盘高度为0
//
if([self isFirstResponder]){
[self textFieldDidBeginEditing:self];
}
}
//开始编辑
- (void) textFieldDidBeginEditing:(UITextField *)textField{
[SSSPublicKeyBoardMoveUpAndDown scrollView:textField andSuperView:[YYYTextField findScrollow:self] isUp:YES];
}
//点击return
- (BOOL)textFieldShouldReturn:(UITextField *)textField;{
[textField resignFirstResponder];
return YES;
}
//结束编辑 恢复WkWebView的frame
- (void)textFieldDidEndEditing:(UITextField *)textField{
UIScrollView *scrollow = [YYYTextField findScrollow:self];
scrollow = scrollow.superview;//WkWebView
[UIView animateWithDuration:0.3 animations:^{
// [(UIScrollView *)sco setContentOffset:CGPointMake(0, 0)];
[(UIScrollView *)scrollow setSize:CGSizeMake(ScreenWidth, ScreenHeight)];
} completion:^(BOOL finished) {
}];
}
+ (UIScrollView *)findScrollow:(UIView *)_selfView{
UIScrollView *scrollow = _selfView;
while (![scrollow isKindOfClass:[UIScrollView class]]) {
if (scrollow.superview == nil) {
return nil;
}
scrollow = scrollow.superview;
//特殊处理
if ([scrollow isKindOfClass:NSClassFromString(@"UITableViewWrapperView")]) {
scrollow = scrollow.superview;
}
}
return scrollow;
}
- (void)dealloc{
//获取系统键盘高度
[[NSNotificationCenter defaultCenter] removeObserver:self];
NSLog(@"dealloc");
}
//移除输入框(点击空白地方 或者 return)
- (BOOL)resignFirstResponder{
//解决输入框remove掉,键盘还在的问题
BOOL isr = [super resignFirstResponder];
return YES;
}
//获取系统键盘高度
- (double)getKeyBoardHeight{
return _keyBoardHeight;
}
SSSPublicKeyBoardMoveUpAndDown 配合键盘进行页面升降
#import
#define ScreenHeight [UIScreen mainScreen].bounds.size.height
#define ScreenWidth [UIScreen mainScreen].bounds.size.width
#define IsIphoneX ((((ScreenWidth == 375) && (ScreenHeight == 812) ) || \
((ScreenWidth == 414) && (ScreenHeight == 896) )) ? 1 : 0)
/**
配合键盘进行页面升降
*/
@interface SSSPublicKeyBoardMoveUpAndDown : NSObject
+ (void)scrollView:(UIView *)view andSuperView:(UIView*)mySuperview isUp:(BOOL)up;
- (void)scrollView:(UIView *)view andSuperView:(UIView*)mySuperview isUp:(BOOL)up;
@end
#import "SSSPublicKeyBoardMoveUpAndDown.h"
#import "YYYTextField.h"
@interface SSSPublicKeyBoardMoveUpAndDown ()
@property(nonatomic,retain)YYYTextField *textFiled;
@end
@implementation SSSPublicKeyBoardMoveUpAndDown
+ (void)scrollView:(UIView *)view andSuperView:(UIScrollView*)mySuperview isUp:(BOOL)up;{
CGRect rect = view.frame;
//坐标系转换
CGRect resultRect = [view.superview convertRect:rect toView:mySuperview];
rect.origin.y = resultRect.origin.y;
SSSPublicKeyBoardMoveUpAndDown *upAndDown = [[SSSPublicKeyBoardMoveUpAndDown alloc]init];
upAndDown.textFiled = (UITextField*)view;
[upAndDown keyboardWillShow:rect direction:up andSuperView:mySuperview];
}
- (void)scrollView:(UIView *)view andSuperView:(UIScrollView*)mySuperview isUp:(BOOL)up;{
CGRect rect = view.frame;
//坐标系转换
CGRect resultRect = [view.superview convertRect:rect toView:mySuperview];
rect.origin.y = resultRect.origin.y;
self.textFiled = (UITextField*)view;
[self keyboardWillShow:rect direction:up andSuperView:mySuperview];
}
- (void)keyboardWillShow:(CGRect)rect direction:(BOOL)isUP andSuperView:(UIScrollView*)mySuperview
{
int temp = ScreenHeight - [self differentKeyBoardHeight] - mySuperview.top;
//视图上移的判断条件放宽20,
if (rect.origin.y + rect.size.height >= temp - 20) {
int distance_ = (rect.origin.y + rect.size.height) - temp;
distance_ += 50;
if (mySuperview.frame.origin.y <= 0) {
CGRect rect = mySuperview.frame;
rect.origin.y = 0;
mySuperview.frame = rect;
}
[self setViewMovedUp:isUP distance:distance_ andSuperView: mySuperview];
}else{
//设置Superview的size
[UIView animateWithDuration:0.3 animations:^{
mySuperview.size = CGSizeMake(ScreenWidth, ScreenHeight - [self differentKeyBoardHeight]);
} completion:^(BOOL finished) {
}];
}
}
- (double)differentKeyBoardHeight{
//
//不同的键盘计算不同的高度
//
double differentKeyBoardHeight = 0;
UIView *inputView = _textFiled.inputView;
NSLog(@"键盘高度%f",inputView.height);
{//系统键盘
if ([_textFiled respondsToSelector:@selector(getKeyBoardHeight)]){
differentKeyBoardHeight = [_textFiled getKeyBoardHeight];
}
if (IsIphoneX) {
differentKeyBoardHeight -= 34;
}
}
//_textFiled.inputView 系统键盘是 nil
if (_textFiled.inputAccessoryView && _textFiled.inputView != nil) {
differentKeyBoardHeight += _textFiled.inputAccessoryView.height;
}
return differentKeyBoardHeight;
}
- (void)setViewMovedUp:(BOOL)movedUp distance:(CGFloat)distance andSuperView:(UIScrollView*)mySuperview{
double oldY = mySuperview.top;
float y = 0.0;
if (movedUp) {
// If moving up, not only decrease the origin but increase the height so the view
// covers the entire screen behind the keyboard.
y -= distance;
} else {
// If moving down, not only increase the origin but decrease the height.
y += distance;
}
CGRect rect = mySuperview.frame;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
// Make changes to the view's frame inside the animation block. They will be animated instead
// of taking place immediately.
rect.origin.y += (y - 60 - 20);
if ([mySuperview isKindOfClass:[UITableView class]]) {
rect.origin.y -= 64;
}
//wkscrollow的frame改变不了只能改wkwebview的
mySuperview.superview.size = CGSizeMake(ScreenWidth, ( ScreenHeight - [self differentKeyBoardHeight] - oldY));
//wkscrollow改变contentOffset
mySuperview.contentOffset = CGPointMake(0, - rect.origin.y);
//最多只到键盘上边挨着
if(-rect.origin.y > (mySuperview.contentSize.height - mySuperview.height)){
mySuperview.contentOffset = CGPointMake(0, (mySuperview.contentSize.height - mySuperview.height));
}
[UIView commitAnimations];
}
@end