怎么解決RN TextInput 被鍵盤遮擋的問題


轉:

https://github.com/dwqs/blog/issues/39

在0.28版rn中,如果textinput的位置在靠近底部的位置,在textinput獲取焦點后,ios上彈出的鍵盤會遮住textinput,導致用戶無法輸入;android上彈出鍵盤時,整個界面會被網上頂,textinput不會被遮住。

在0.28中,解決ios上該問題的方式是利用 ScrollView contentInset 屬性,監聽鍵盤的彈出和隱藏事件(keyboardWillShow/keyboardWillHide),獲取鍵盤的高度,動態設置成 contentInset 的值。

將rn升級成0.33后,android和ios上都會出現TextInput 被鍵盤遮擋的問題,ios上原來的方式也不能解決此問題了。

在 ios 上,textinput 未獲取焦點前:

image

獲取焦點后:

image

textinput被鍵盤擋住了。android上有同樣的問題。

解決這種情況的一種方式,監聽鍵盤的彈出和隱藏事件,在ScrollView底部設置一個占位符組件,將占位符的高度設置成鍵盤的高度。

監聽鍵盤事件:

this.keyboardShow = Platform.OS === 'ios' ?
    Keyboard.addListener('keyboardWillShow',this.updateKeyboardSpace.bind(this)) : Keyboard.addListener('keyboardDidShow',this.updateKeyboardSpace.bind(this));
this.keyboardHide = Platform.OS === 'ios' ?
    Keyboard.addListener('keyboardWillHide',this.resetKeyboardSpace.bind(this)) : Keyboard.addListener('keyboardDidHide',this.resetKeyboardSpace.bind(this));

在事件處理程序中,獲取鍵盤高度:

updateKeyboardSpace(frames){
    if(!frames.endCoordinates){
       return;
    }
    let keyboardSpace = frames.endCoordinates.height;//獲取鍵盤高度

    this.setState({
        keyboardSpace: keyboardSpace
    })
}

最后將高度傳遞給占位符組件:

<ScrollView>
    //其他元素 
    <KeyboardSpacer keyboardSpace={this.state.keyboardSpace}/>
</ScrollView>

KeyboardSpacer組件實現如下:

const styles = StyleSheet.create({
    container: {
        left: 0,
        right: 0,
        bottom: 0
    }
});

export default class KeyboardSpacer extends Component {
    constructor(){
        super();
    }

    static propTypes = {
        keyboardSpace: PropTypes.number
    };

    static defaultProps = {
        keyboardSpace: 0
    };

    render() {

        let {keyboardSpace} = this.props;
        return (
            <View style={[styles.container, { height: ~~keyboardSpace }]} />
        );
    }
}

效果如下:

image

這樣子能解決部分場景,例如textInput的位置是靠近底部的。如果textinput框的位置是靠近頁面上部的,那么textinput框會被頂上去,就會因超出ScrollView的視口范圍而被“遮住”。

這時,就不能單純的將鍵盤的高度給 KeyboardSpacer 了,而應該根據textinput在ScrollView視口的位置進行 KeyboardSpacer 高度的計算了。

在頁面加載之后,能獲取到 ScrollView的視口高度ViewportHeight,這個值是保持不變的。此外,也能拿到textinput距離ScrollViewd頂邊的垂直距離InputY,這個值是固定的,不會隨着頁面的滾動而變化頁面示意如下:

1

在界面滾動一定距離之后,頁面示意如下:

2

紅邊表示此時ScrollView的頂邊位置,虛線框表示textInput框的原位置,實體框表示textInput在頁面滾動之后的位置。

頁面滾動時,能獲取到ScrollView已經滾動的偏移量 scrollY,此時,就能計算出此時 textInput 距離ScrollView視口底部的距離 InputToBottom:

InputToBottom = ViewportHeight - (InputY - scrollY + textInput的高度)

此時,應該根據InputToBottom與鍵盤高度的大小比較來設置 keyboardSpace:

keyboardHeight = frames.endCoordinates.height;  //鍵盤高度
keyboardSpace = InputToBottom >= keyboardHeight ? 0 : keyboardHeight - InputToBottom;

在圖示頁面的布局中,還有一個底部元素,因而在計算 keyboardHeight 時,因考慮下實際情況是否需要減去底部元素的高度或者ScrollView的marginBottom值。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM