详解React-Native解决键盘遮挡问题(Keyboard遮挡问题)

前端之家收集整理的这篇文章主要介绍了详解React-Native解决键盘遮挡问题(Keyboard遮挡问题)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

本文介绍了React-Native键盘遮挡问题,分享给大家

在开发中经常遇到需要输入的地方,RN给我们提过的TextInput虽然好用,可惜并没有处理遮挡问题。

很多时候键盘弹出来都会遮挡住编辑框,让人很头疼。

本来想在js.coach 库里面找一找第三方的插件,看到最好的一个就是React-native-keyboard-spacer了,然而我们还差一个东西,那就是获取键盘的高度。

这个我也查了半天并没有提供,获取没找到吧。于是只好自己写原生模块去获取键盘的高度了。

关于原生iOS获取键盘高度我就不多说了,网上一大堆,我直接贴上我的代码,自己根据RN写的原生模块:

import <UIKit/UIKit.h>

import "RCTEventEmitter.h"

import "RCTBridgeModule.h"

@interface KeyboardHeight : RCTEventEmitter

-(void)heightChanged:(int)height;

@property (nonatomic,assign)int kbHeight;

@end

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方面,这个也是老话题了,前面的博客都说了,直接贴代码

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);

}
componentWillUnmount() {
this.heightChanged.remove();
}
_heightChanged(data){
// console.log(data);
this.keyboardHeight = data;
this.changeMarginTop();//这里我是处理高度的
}

这里已经拿到高度,接下来就好办了,就是加减问题。

我们需要拿到输入框在屏幕中的位置,然后和键盘的高度做比较,输入框的位置我们通过onLayout获取

ScreenHeight - this.keyboardHeight){ drawLayout.setKBMoveY(-(this.orgLayoutParent.y + layout.y + layout.height - ScreenHeight + this.keyboardHeight)); }else{//不对的置零处理 drawLayout.setKBMoveY(0); } } render() { return ( //这里获取的是相对位置哦 //点击回车时的调用,这里可以根据需求去做 发送 ); }

如果你是当前一个组件一个页面,就没必要像我这样做了,加了一个global,去记录它们的祖父组件(主要是整个页面向上移动)

距离我们也都算好了,接下来就是给drawLayout加一个动画,然后动起来不要那么突兀。

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}}/>

); } }

这就大功告成了。接着截图看看效果,虽然有动画,没法弄动态图

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。

原文链接:https://www.f2er.com/js/37882.html

猜你在找的JavaScript相关文章