zoukankan      html  css  js  c++  java
  • 怎么解决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值。

  • 相关阅读:
    JDK源码解析(一)ArrayList源码解析
    vmware fusion 找不到可以连接的有效对等进程
    SecureCRT通过密钥登录
    Mac下的SecureCRT使用技巧
    Mac securecrt 破解版安装
    sourcetree pull push需要密码问题
    tp 下载
    switch 失效
    如何安装 Composer
    php 防盗链
  • 原文地址:https://www.cnblogs.com/jveguo/p/6092341.html
Copyright © 2011-2022 走看看