2016年10月25日更新:

  现在有一个更准确一点的做法是用一个View包裹住TextInput,然后通过该View的onLayout方法获取该输入框的y轴位置,再减去一个适当的高度去处理scrollview的滚动,如下所示:

<View onLayout={this._downloadLayout.bind(this)}
style={{marginLeft:15,flexDirection: 'column',alignItems:'flex-start'}}>
<TextInput
style={styles.inputStyle}
defaultValue={this.state.downloadUrl}
placeholder = '输入下载地址'
ref = 'downloadInput'
onFocus = {this._downLoadFocus.bind(this)}
onChangeText={(text) => this.setState({downloadUrl:text})}
/>
</View>
然后实现_downloadLayout方法:

_downloadLayout(e){
    this.setState({
downloadY:e.nativeEvent.layout.y,
});
}
之后再实现TextInput的onFocus方法,对包裹的整个scrollview页面进行滚动:
_downLoadFocus(){
let scroller = this.refs.scroller;
iOS&& setTimeout(()=>{
let y = this.state.downloadY - 1/3*Dev_height;//Dev_height为屏幕的高度
scroller&&scroller.scrollTo({x:0, y:y, animated:true});
},50);
}
这样的处理适合大多数的情况。
评论里有小伙伴说React.findNodeHandle已经不可以使用了,应该是使用了rn更新的版本,所以我们在使用的时也需要根据版本的不同去选择合适的方法,
感谢他的提醒,新版本可以使用下面这个方法
import ReactNative from 'react-native';
...
ReactNative.findNodeHandle(...)

RN中要解决键盘遮挡输入框的问题其实有挺多方式,在这里只是记录其中的一些个人实际开发中使用到的。

方式一、使用scrollTo方法,这也是最简单最粗暴的,只是需要计算scrollview滚动的距离,并且处理一些体验的bug问题。大致思路是:组件render方法中使用scrollview,并且设置scrollview的keyboardShouldPersistTaps={true}(此步一定不能少,如果缺少该属性,接下来的一步将会不起作用),然后在scrollview中用一个view作为container包裹所有剩余的子视图,比如Text,TouchableHighlight之类的,并且用onStartShouldSetResponderCapture截取该view的事件,用以解决当点击页面上的按钮时,第一次点击只会收起键盘,第二次点击才会响应按钮方法的bug。然后在TextInput的onFocus方法中滚动scrollview,在onEndEditing中恢复scrollview的滚动。以下是在具体实现中的代码。

render方法的实现:

render:function() {

  return(
    <View style={styles.container}>
    <NavigationBar title={'绑定手机号'} onBackPress={this.onBackPress}/>
    <ScrollView ref='scroll' keyboardShouldPersistTaps={true} >
      <View style={styles.content} onStartShouldSetResponderCapture={(e) => {
        const target = e.nativeEvent.target;
        if (target !== React.findNodeHandle(this.refs.phoneInput) && target !== React.findNodeHandle(this.refs.codeInput)) {
          this.refs.phoneInput.blur();
          this.refs.codeInput.blur();
        }}}>

        <TextInput
          style = {styles.cardNumText}
          ref = 'phoneInput'
          onFocus={this.scrollViewTo.bind(this)}
          onEndEditing={()=>{this.refs.scroll.scrollTo(0)}}
          onChange = {this.cardNumberTextChanged.bind(this)}
          placeholder = '请输入预留手机号'
          placeholderTextColor = '#481A5C'
          keyboardType = 'numeric'
        />

        <View style = {styles.lineView}></View>

          <TouchableHighlight style = {styles.topButton} underlayColor='#9B9B9B' onPress = {this.jumpToNextPage.bind(this)}>
            <Text style = {styles.buttonText}>发送验证码</Text>
          </TouchableHighlight>
        <TextInput
          style = {styles.cardNumText}
          ref = 'codeInput'
          onFocus={this.scrollViewTo.bind(this)}
          onEndEditing={()=>{this.refs.scroll.scrollTo(0)}}
          placeholder = '输入验证码'
          placeholderTextColor = '#999'
          onChange = {this.cardNumberTextChanged}
          keyboardType = 'number-pad'
        />
        <View style = {styles.lineView}></View>

        <Text style = {styles.protectText}>
           XXXXXXXXXXXXXXXXXXX
        </Text>

        <TouchableHighlight style = {styles.downButton} underlayColor='#481A5C' onPress = {this.jumpToNextPage.bind(this)}>
          <Text style = {styles.buttonText}>下一步</Text>
        </TouchableHighlight>
      </View>
    </ScrollView>
  </View>);
}

  onFocus时调用的scrollViewTo方法的实现:

  scrollViewTo:function(e){
    let target = e.nativeEvent.target;
    let scrollLength = 100;
    if (target=== React.findNodeHandle(this.refs.codeInput)) {
      scrollLength = 160;
    }
    this.refs.scroll.scrollTo(scrollLength);
  },

  方式二、使用View包裹时,通过设置View的marginTop属性并且结合动画来实现:初始化一个state对象的值viewMarginTop用于设置Animated.View的marginTop,在textInput的onfocus时改变viewMarginTop的值,在onEndediting时恢复或者设置新的marginTop。具体为首先引入Animated,并且初始化state方法。(state内值的变化会触发界面上相关元素的再次熏染,具有reactivecocoa的相同的作用)

  getInitialState: function () {
    return {
      viewMarginTop: new Animated.Value(0),
    };
  },

在需要上升的视图中使用Animated.View,设置其mairginTop为viewMarginTop

<Animated.View style={{marginTop:this.state.viewMarginTop}}>

    //当然不建议将样式写在这里,这样会导致每次熏染都创建一次样式,你应该将样式定义到StyleSheet中

    //your Views and component

</Animated.View>

然后在onFucos的方法中用动画改变viewMarginTop的值,如下

  Animated.timing(
    this.state.viewMarginTop,
    {
      toValue: 160,
      duration: 250,
    }
  ).start();

要恢复只需要在onEndediting中用同样的原理恢复viewMarginTop的值即可.

方式三、通过监听scrollview上键盘的出现和消失,在出现和消失方法中设置某个state值的变化,来设置scrollview的contentInset,该方法只是在github上看过,具体本人并没有用过即:

1.在页面熏染完时添加监听

componentDidMount: function () {
  // Keyboard events监听
  DeviceEventEmitter.addListener('keyboardWillShow', this.updateKeyboardSpace)
  DeviceEventEmitter.addListener('keyboardWillHide', this.resetKeyboardSpace)
},

componentWillUnmount: function () {
  // TODO: figure out if removeAllListeners is the right thing to do
  DeviceEventEmitter.removeAllListeners('keyboardWillShow')
  DeviceEventEmitter.removeAllListeners('keyboardWillHide')
},

getInitialState: function (props) {//初始化变量
  this.viewIsInsideTabBar = false
  return {
    keyboardSpace: 0,
  }
},

// Keyboard actions
updateKeyboardSpace: function (frames) {
  const keyboardSpace =  frames.endCoordinates.height//获取键盘高度
  this.setState({
    keyboardSpace: keyboardSpace,
  })
},

resetKeyboardSpace: function () {
  this.setState({
    keyboardSpace: 0,
  })
},

//设置scrollview的contentInset

<ScrollView
  ref='keyboardView'
  keyboardDismissMode='interactive'
  contentInset={{bottom: this.state.keyboardSpace}}
  showsVerticalScrollIndicator={true}
</ScrollView>

React-native键盘遮挡输入框问题的解决的更多相关文章

  1. react native 键盘遮挡按钮点击事件

    在做项目的时候,我遇到一个很奇怪的问题,我先描述一下问题,在InputText输入内完成以后,点击按钮进行下一步的操作的时候,第一次点击的时候,按钮没有响应,第二次点击的时候才会响应.这样对用户体验有 ...

  2. iOS键盘遮挡输入框,输入区域自动上移

    在iOS开发过程当中,遇到关于键盘遮挡输入框的问题,经过网络参考与实践,总结如下: 登录窗口,上下放置两个UITextField,一个用户名,一个密码,放置的在屏幕下方1/3处,当点击用户名时,自动弹 ...

  3. [RN] React Native 键盘管理 在Android TextInput遮盖,上移等问题解决办法

    React Native 键盘管理 在Android TextInput遮盖,上移等问题解决办法 解决办法: 打开android工程,在AndroidManifest.xml中配置如下: <ac ...

  4. iOS- UITextView与键盘回收与键盘遮挡输入框

    一.UITextView 可以实现多行输入的文本框,基本属性与UITextField相似,可以输入多行,可以滚动.UITextView还有个代理方式- (BOOL)textView:(UITextVi ...

  5. iOS 键盘遮挡输入框万能解决方案(多个输入框)

    效果图如下: 思路分析: 代码: 知识点: 问题: 效果图如下: 思路分析: 当我们有很多输入框时,有时候键盘弹出来会遮挡着输入框.我们需要获取输入框和键盘相对于最外层视图的位置来判断是否遮挡,如果遮 ...

  6. react-native 键盘遮挡输入框

    Android上已经自动对键盘遮挡输入框做了处理,所以我们只需要关注ios. 1.首先引入 KeyboardAvoidingView import { KeyboardAvoidingView } f ...

  7. iOS Android中 h5键盘遮挡输入框的问题和解决方案

    问题发现:在 Android 部分机型 和 iOS部分系统下 键盘会出现遮挡输入框的情况(壳内).问题解决: Android 经过测试,Android 的6.0版本以上均会出现改问题,归根到底是之前的 ...

  8. iOS 开发之路(登陆页键盘遮挡输入框问题)一

    在学习开发登陆页的时候,遇到的问题分享如下: 首先是swift 3.0 中,NotificationCenter 设置 selector 如下: @IBOutlet weak var bottomCo ...

  9. android webview 输入法键盘遮挡输入框的问题

    新建一个工具类: /** * 解决webView键盘遮挡问题的类 * Created by zqy on 2016/11/14. */ public class KeyBoardListener { ...

随机推荐

  1. 什么是js事件,冒泡机制,事件捕获,默认行为

    js事件: javascript使我们能够有能力创建动态页面,事件就是可以被js侦测到的行为,网页中每个元素都可以产生某些触发js函数的事件. 例如我们可以在用户点击某个按钮时产生一个click事件来 ...

  2. 力扣 - 剑指 Offer 53 - I. 在排序数组中查找数字 I

    题目 剑指 Offer 53 - I. 在排序数组中查找数字 I 思路1 一般来说,首先想到的是使用一个变量,从头开始遍历整个数组,记录target数组出现的次数,但是这样的时间复杂度是O(n),还是 ...

  3. HTML中的emment

    emment的优点和使用方法: 优点:Emment是前端开发者必备的工具,使用它可以大大提高前端开发效率. 使用方法:Emment的使用方法非常简单,直接在编辑器上输入HTML和CSS代码的缩写,然后 ...

  4. .net 5.0 ref文件夹的作用

    ref目录里的dll是一个名为参考组件的东西,微软MSDN给的解释是 参考组件是一种特殊类型的程序集,仅包含表示库的公共API面所需的最小元数据数量.它们包括用于在构建工具中引用程序集时重要的所有成员 ...

  5. Idea Maven auto Import

  6. [no code][scrum meeting] Alpha 9

    项目 内容 会议时间 2020-04-15 会议主题 OCR验收 会议时长 15min 参会人员 OCR组成员 $( "#cnblogs_post_body" ).catalog( ...

  7. BUAA_2020_软件工程_结对项目作业

    项目 内容 这个作业属于哪个课程 班级博客 这个作业的要求在哪里 作业要求 我在这个课程的目标是 掌握软件工程的思路方法 这个作业在哪个具体方面帮助我实现目标 学习结对编程 教学班级 006 项目地址 ...

  8. 浅谈如何爆踩TLEcoders

    对付一些速度比老奶奶都慢的评测姬, 除了超级小的常数,往往还不得不使用一些不算办法的办法 比如说这个让人无语的$ACcoders$的评测姬, 当我们感到代码已经无法再卡常的时候,对人生已经近乎绝望的时 ...

  9. PCB中,Solder Mask与Paste Mask有啥区别呢?

    Solder Mask Layers: 即阻焊层.顾名思义,他的存在是为了防止PCB在过波峰焊的时候,不应涂锡的地方粘上锡. 可以简单理解为一个洞,该区域(洞)以外的地方,都不允许有焊锡,即只能涂绿油 ...

  10. dhcpd:bad subnet number/mask combination. subnet

    今天在调试wifi热点启动hdcpd服务时出现报错"bad subnet number/mask combination. subnet 192.168.1.1", Interne ...