在开发中经常遇到需要输入的地方,RN给我们提过的TextInput虽然好用,可惜并没有处理遮挡问题。
很多时候键盘弹出来都会遮挡住编辑框,让人很头疼。
本来想在js.coach 库里面找一找第三方的插件,看到最好的一个就是React-native-keyboard-spacer了,然而我们还差一个东西,那就是获取键盘的高度。
这个我也查了半天并没有提供,获取没找到吧。于是只好自己写原生模块去获取键盘的高度了。
关于原生iOS获取键盘高度我就不多说了,网上一大堆,我直接贴上我的代码,自己根据RN写的原生模块:
// // KeyboardHeight.h // Jicheng6 // // Created by guojicheng on 16/11/7. // Copyright © 2016年 Facebook. All rights reserved. // #import <UIKit/UIKit.h> #import "RCTEventEmitter.h" #import "RCTBridgeModule.h" @interface KeyboardHeight : RCTEventEmitter<RCTBridgeModule> -(void)heightChanged:(int)height; @property (nonatomic, assign)int kbHeight; @end
// // KeyboardHeight.m // Jicheng6 // // Created by guojicheng on 16/11/7. // Copyright © 2016年 Facebook. All rights reserved. // #import "KeyboardHeight.h" @implementation KeyboardHeight RCT_EXPORT_MODULE(); - (instancetype)init { self = [super init]; if (self) { self.kbHeight = 0; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil]; } return self; } -(void)keyboardDidShow:(NSNotification*) aNotification { //获取键盘的高度 NSDictionary *userInfo = [aNotification userInfo]; NSValue *aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey]; CGRect keyboardRect = [aValue CGRectValue]; if (_kbHeight != keyboardRect.size.height){ _kbHeight = keyboardRect.size.height; [self heightChanged:_kbHeight]; } } RCT_REMAP_METHOD(getKBHeight, resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { resolve([[NSNumber alloc]initWithInt:_kbHeight]); } - (NSArray<NSString *> *)supportedEvents { return @[@"heightChanged"]; } -(void)heightChanged:(int)height { [self sendEventWithName:@"heightChanged" body:[NSNumber numberWithUnsignedInt:height]]; } @end
这里其实我前面的博客也说过,一开始我想的是通过RCT_REMAP_METHOD去获得高度,可惜在键盘第一次弹出的时候,并不是弹出之后的高度,获取之后依然是0,所以添加了一个监听函数heightChanged,当记录的值和改变的值不一致时,调用监听函数,将值传给JS端。这样就可以在检测变化之后JS端做相应的变化。
好了,原生模块封装好了,接下来看js方面,这个也是老话题了,前面的博客都说了,直接贴代码:
import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, View, TouchableOpacity, Alert, TextInput, PixelRatio, Linking, Keyboard, NativeEventEmitter, } from 'react-native'; var Dimensions = require('Dimensions'); var ScreenWidth = Dimensions.get('window').width; var ScreenHeight = Dimensions.get('window').height; var kbHeight = require('NativeModules').KeyboardHeight; const kbHeightEvt = new NativeEventEmitter(kbHeight);
componentWillMount() { this.heightChanged = kbHeightEvt.addListener('heightChanged', this._heightChanged.bind(this)); } componentDidMount() { } componentWillUnmount() { this.heightChanged.remove(); } _heightChanged(data){ // console.log(data); this.keyboardHeight = data; this.changeMarginTop();//这里我是处理高度的 }
这里已经拿到高度,接下来就好办了,就是加减问题。
我们需要拿到输入框在屏幕中的位置,然后和键盘的高度做比较,输入框的位置我们通过onLayout获取:
onLayoutParent(event){ if (this.orgLayoutParent == null){//获取的父组件的位置,因为要用到计算 this.orgLayoutParent = event.nativeEvent.layout; } console.log('parent layout: ', event.nativeEvent.layout); } onLayoutMail(event){//获取输入框的位置,这个位置是相对父组件的位置,所以上面需要获得父组件的 this.layoutMail = event.nativeEvent.layout; } onFocusMail(event){ this.focusName = 'mail';//定义一个标识,可以区分不同输入框 this.changeMarginTop();//统一处理高度的函数 } onSubmitMail(){ drawLayout.setKBMoveY(0);//当输入完毕时,重置回原来的状态 } changeMarginTop(){//计算移动的距离 var layout = null; if (this.focusName == 'mail'){ layout = this.layoutMail; } if (layout && this.orgLayoutParent.y + layout.y + layout.height > ScreenHeight - this.keyboardHeight){ drawLayout.setKBMoveY(-(this.orgLayoutParent.y + layout.y + layout.height - ScreenHeight + this.keyboardHeight)); }else{//不对的置零处理 drawLayout.setKBMoveY(0); } } render() { return ( <View style={[styles.container, this.props.style ? this.props.style : {}]} onLayout={this.onLayoutParent.bind(this)}> <View style={[styles.viewStyle, {marginTop: 10}]} onLayout={this.onLayoutMail.bind(this)}>//这里获取的是相对位置哦 <TextInput style={styles.textInputStyle} onChangeText={this.onTextChange.bind(this)} value={this.state.emailPath} placeholder={'请输入邮箱'} onFocus={this.onFocusMail.bind(this)}//当获取到焦点时触发 onSubmitEditing={this.onSubmitMail.bind(this)}/>//点击回车时的调用,这里可以根据需求去做 <TouchableOpacity onPress={this.onSubmitSend.bind(this)}> <View style={[styles.sendButtonView, {}]}> <Text style={styles.sendButtonText}> 发送 </Text> </View> </TouchableOpacity> </View> </View> ); }
如果你是当前一个组件一个页面,就没必要像我这样做了,加了一个global,去记录它们的祖父组件(主要是整个页面向上移动)
距离我们也都算好了,接下来就是给drawLayout加一个动画,然后动起来不要那么突兀。
import React, { Component } from 'react'; import { StyleSheet, Text, View, TouchableOpacity, Animated, } from 'react-native'; import SendEmail from './SendEmail'; export default class DrawLayout extends Component { constructor(props){ super(props); this.state={ kbShowY: new Animated.Value(0),//设置动画的初始值 }; global.drawLayout = this;//这里将自己保存到global里面,方便它的子组件调用 } setKBMoveY(y){ Animated.timing(//这里用的是timing均匀变化,具体的参数,可以参考RN的文档,写的很详细了,这里就不啰嗦了。 this.state.kbShowY,{ toValue: y,//变化到目的位置 delay: 250,//延时250毫秒 }, ).start();//开始 } componentWillUnmount() { global.drawLayout = null;//降这个值赋值为空 } render() { return ( <Animated.View style={[styles.container, {marginTop: this.state.kbShowY}]} >//使用Animated.View <SendEmail style={{marginTop: 10}}/> </Animated.View> ); } }
这就大功告成了。接着截图看看效果,虽然有动画,没法弄动态图
以上是React-Native遇到Keyboard遮挡问题该如何解决?的详细内容。更多信息请关注PHP中文网其他相关文章!

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

JavaScript在现实世界中的应用包括服务器端编程、移动应用开发和物联网控制:1.通过Node.js实现服务器端编程,适用于高并发请求处理。2.通过ReactNative进行移动应用开发,支持跨平台部署。3.通过Johnny-Five库用于物联网设备控制,适用于硬件交互。

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。 1.Python以简洁语法和丰富库生态着称,适用于数据分析和Web开发。 2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。

SublimeText3 英文版
推荐:为Win版本,支持代码提示!

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)