Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

KeyboardAvoidingView overlapping screen on iPhone X

I currently have a KeyboardAvoidingView with a hard-coded keyboardVerticalOffset of 64. This works fine on the iPhone but is about 20px short on the iPhone X.

The component looks like this:

<KeyboardAvoidingView behavior='padding' keyboardVerticalOffset={ 64 }>
  <View style={ styles.messageList }>
    ...
  </View>
  <View style={ styles.messageInput }>
    ...
  </View>
</KeyboardAvoidingView>

Is there a better way to determine what keyboardVerticalOffset should be than hard coding a value? Is there something else I could be doing differently with component placement? I'm open to any suggestions.

iPhone 8

enter image description here

iPhone X

enter image description here

like image 226
anthonator Avatar asked Dec 13 '17 17:12

anthonator


3 Answers

This is caused by the status bar height being different for iphoneX. (you also get the same issue with other iphones if you toggle the 'in-call' status bar using ⌘Y in the simulator).

You can get the status bar height and use this to set the keyboardVerticalOffset value of the KeyboardAvoidingView. (in our case this was 44 + statusBarHeight)

import React, {Component} from 'react';
import {KeyboardAvoidingView, NativeModules, StatusBarIOS} from 'react-native';

const {StatusBarManager} = NativeModules;

export class IOSKeyboardAvoidingView extends Component {

  state = {statusBarHeight: 0};

  componentDidMount() {
    StatusBarManager.getHeight((statusBarFrameData) => {
      this.setState({statusBarHeight: statusBarFrameData.height});
    });
    this.statusBarListener = StatusBarIOS.addListener('statusBarFrameWillChange', (statusBarData) => {
      this.setState({statusBarHeight: statusBarData.frame.height});
    });
  }

  componentWillUnmount() {
    this.statusBarListener.remove();
  }

  render() {
    const {style, children} = this.props;
    return (
      <KeyboardAvoidingView
        behavior="padding"
        keyboardVerticalOffset={44 + this.state.statusBarHeight}
        style={style}
      >{children}
      </KeyboardAvoidingView>
    );
  }
}
like image 124
TimT Avatar answered Nov 01 '22 20:11

TimT


Please refer to : https://stackoverflow.com/a/51169574/10031014 for similar issues

like image 6
Toh Ban Soon Avatar answered Nov 01 '22 20:11

Toh Ban Soon


I have used a custom component to overcome this situation.

import React from "react";
import {Animated, Keyboard} from "react-native";

export default class KeyboardAwareComponent extends React.Component {

    constructor(props) {
        super(props)
        this.keyboardHeight = new Animated.Value(0);
    }

    componentWillMount () {
        this.keyboardWillShowSub = Keyboard.addListener('keyboardWillShow', this.keyboardWillShow);
        this.keyboardWillHideSub = Keyboard.addListener('keyboardWillHide', this.keyboardWillHide);
    }

    componentWillUnmount() {
        this.keyboardWillShowSub.remove();
        this.keyboardWillHideSub.remove();
    }

    keyboardWillShow = (event) => {
        Animated.parallel([
            Animated.timing(this.keyboardHeight, {
                duration: event.duration,
                toValue: event.endCoordinates.height,
            })
        ]).start();
    };

    keyboardWillHide = (event) => {
        Animated.parallel([
            Animated.timing(this.keyboardHeight, {
                duration: event.duration,
                toValue: 0,
            })
        ]).start();
    };

    render(){
        const {children, style, ...props} = this.props
        return(
            <Animated.View style={[{flex:1,alignItems:'center',paddingBottom: this.keyboardHeight},style]} {...props}>
                {children}
            </Animated.View>
        );
    }

}

Just use the component "KeyboardAwareComponent" as a root component of any page. It will automatically adjust the view when keyboard will show or hide.

Example:---

YourComponent extends React.Component{
    render(){
        <KeyboardAwareComponent>
            {Your child views}
        </KeyboardAwareComponent>
    }
}
like image 3
srs Avatar answered Nov 01 '22 20:11

srs