国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

詳解React-Native解決鍵盤遮擋問題(Keyboard遮擋問題)

2019-11-19 16:05:11
字體:
來源:轉載
供稿:網友

本文介紹了React-Native鍵盤遮擋問題,分享給大家

在開發中經常遇到需要輸入的地方,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的文檔,寫的很詳細了,這里就不

主站蜘蛛池模板:
时尚|
房产|
鲁甸县|
威海市|
包头市|
沂南县|
彩票|
华安县|
滨海县|
龙泉市|
北海市|
罗江县|
平顶山市|
承德市|
邯郸市|
麟游县|
永福县|
叶城县|
获嘉县|
农安县|
潍坊市|
盐亭县|
拜城县|
沙洋县|
枣阳市|
嘉善县|
芦溪县|
南昌县|
渑池县|
岱山县|
拉萨市|
肃南|
水富县|
修水县|
尖扎县|
云浮市|
乃东县|
榆社县|
松江区|
清丰县|
阿拉善右旗|