1. 程式人生 > >React-native鍵盤遮擋輸入框問題的解決

React-native鍵盤遮擋輸入框問題的解決

  現在有一個更準確一點的做法是用一個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鍵盤遮擋輸入問題的解決

  現在有一個更準確一點的做法是用一個View包裹住TextInput,然後通過該View的onLayout方法獲取該輸入框的y軸位置,再減去一個適當的高度去處理scrollview的滾動,如下所示: <View onLayout={this._downloadLa

iOS 鍵盤遮擋輸入解決方案

// 方法一 - (void)addNotification { [[NSNotificationCenterdefaultCenter] addObserver:selfselector:

React鍵盤遮擋輸入

很多情況下,我們需要在介面中進行輸入資訊,免不了TextInput元件,但是問題來了,有時候鍵盤彈上來的位置正好遮住了輸入框,使用者根本看不到自己輸入了什麼。 這裡面有一個非常簡單的方法來實現: i

iOS解決鍵盤遮擋輸入問題

導讀:UITextField(輸入框)獲取焦點後會彈出鍵盤,有時候鍵盤會遮擋住輸入框,影響使用者互動,所以需要在彈出鍵盤的時候將檢視上移至不會遮擋的位置。下面主要講述幾種常見解決方法。 一、彈出鍵盤時,將整個檢視上移:監聽鍵盤事件 //監聽鍵盤 //1、鍵盤彈出時

解決鍵盤遮擋輸入的問題

根據前人經驗總結普通Activity(不帶WebView),直接使用adjustpan或者adjustResize如果帶WebView:a) 如果非全屏模式,可以使用adjustResizeb) 如果是全屏模式,則使用AndroidBug5497Workaround進行處理。

js解決鍵盤遮擋輸入問題

經驗須知 彈出軟鍵盤時: ios端$(‘body’).scrollTop()會改變android端$(window).height()會改變拉起鍵盤不是一瞬間,而是有一個緩動過程 問題重現 ios端,經常會出現輸入法遮擋輸入框的問題(特別是那種有一個白色頂部的輸入法,如:

swift開發筆記24 解決鍵盤遮擋輸入 的方法

func textViewDidBeginEditing(textView:UITextView) {         UIView.animateWithDuration(0.4, anim

Android WebView 軟鍵盤遮擋輸入問題的解決方法

1. 在java程式碼中設定 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); 2. 在

移動端Android軟鍵盤遮住輸入解決

res set pan area app tar span lac row 在使用vue的情況下,在輸入框中添加 <textarea class="textarea" @click="isAndroid" :maxlength="30" :rows="1" plac

android全屏/沉浸式狀態列下,各種鍵盤擋住輸入解決辦法

*本篇文章已授權微信公眾號 guolin_blog (郭霖)獨家釋出 在開發中,經常會遇到鍵盤擋住輸入框的情況,比如登入介面或註冊介面,彈出的軟鍵盤把登

WebView使用中的那些坑之軟鍵盤遮擋輸入

一、測試環境: HuaWei U9508 4.2.2 二、問題: 在ViewPager的一個Fragment頁面中只有一個WebView,用於載入url,但是最下面的輸入框點選後被軟鍵盤遮擋

React-Native鍵盤遮擋問題進階發現

我在前面也寫了一篇關於鍵盤遮擋問題的解決方案,這次的原理也差不多,不過在後續的研究中發現官方給了一個有意思的元件叫 KeyboardAvoidingView。然後就動手去試了一試,然而效果並不好!具體用法可以參考這裡:點選開啟連結 不過隨著RN的更新,這個官網肯定會解決

iOS- UITextView與鍵盤迴收與鍵盤遮擋輸入

可以實現多行輸入的文字框,基本屬性與UITextField相似,可以輸入多行,可以滾動。UITextView還有個代理方式- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementTex

h5鍵盤遮擋輸入問題 、模仿微信輸入失去焦點時隱藏iphone的軟鍵盤和聚焦時出現輸入

最近的專案做得是混合開發,其實比較尷尬的啦,手機端的安卓與ios挺多相容問題的。 1、手機端h5頁面中輸入法鍵盤會遮擋輸入框的問題。       $('input').on('focus',function(event){              //自動反彈 輸入法高度

移動端手機軟鍵盤遮擋輸入問題

頁面: <section class="links"> <h3 class="title">聯絡方式</h3> <div class="c

[ios]TableView的Cell中有Textfield時放置鍵盤遮擋輸入

tableview初始化時- (UITableView *)tableView { if (!_tableView) { UITableViewController* tvc=

Android:鍵盤擋住輸入解決辦法

分類: Android 2011-05-28 00:10 83人閱讀 評論(0) 收藏 舉報 大家在佈局時候,有時候會發現輸入框被擋住一部分,能完全顯示出來,但是系統自帶簡訊介面 可以完全漂浮在軟鍵盤之上,看了一下簡訊原始碼,修改一下輸入模式就可以了,原始碼如下 程式碼方

React Native TextInput鍵盤遮擋輸入款問題

當我們使用TextInput輸入框控制元件的時候經常容易被鍵盤所遮擋,在React Native上,安卓不會出現此問題,iOS小螢幕的手機出現比較明顯。 iOS原生開發中可以有代理進行監聽進行上下滾動

Solution of issue: Android soft keyboard overlap with input div on browser【Android虛擬鍵盤輸入重疊解決方案】

Android soft keyboard overlap with input div on browser 【Android虛擬鍵盤與輸入框重疊】 給個英文標題,因為我知道絕大部分人搜資料都用英文搜。 問題: 在Android裝置瀏覽器上開啟自己的頁面,當點選頁面底部的輸入框時,虛擬

解決ios底部固定輸入,獲取焦點時彈出輸入法鍵盤擋住輸入

ios端比較常見的,就是在頁面底部固定的輸入框,如下,一旦獲取焦點,彈出的輸入法鍵盤就會把input輸入框完全擋住,解決方法很簡單,加上下面的幾行程式碼即可       $(".replay_text").on("click", functi