The keyboard in floating mode is having problem.
Description
My app has been rejected by apple due to interface issues.
After half a day I queried the problem, I finally realized the problem was at the floating keyboard of iPadOS 13.
When the keyboard went into floating mode, KeyboardAvoidingView worked incorrectly and destroyed my interface structure.
React Native version:
System:
OS: macOS 10.15.3
CPU: (4) x64 Intel(R) Core(TM) i3-8100B CPU @ 3.60GHz
Memory: 400.56 MB / 8.00 GB
Shell: 5.7.1 - /bin/zsh
Binaries:
Node: 14.5.0 - /usr/local/bin/node
npm: 6.14.5 - /usr/local/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 13.6, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
IDEs:
Android Studio: 4.0 AI-193.6911.18.40.6514223
Xcode: 11.6/11E708 - /usr/bin/xcodebuild
npmPackages:
react: 16.9.0 => 16.9.0
react-native: 0.61.5 => 0.61.5
npmGlobalPackages:
react-native-cli: 2.0.1
react-native-rename: 2.4.1
Expected Results
What I want now to be able to recognize a certain event is to notify the keyboard to switch to floating mode, from which I will handle my UI.
Snack, code example, screenshot, or link to a repository:
Screen capture when keyboard is in anchor mode.

Screen capture when the keyboard is in floating mode.

Code:

| :warning: | Missing Reproducible Example |
|---|---|
| :information_source: | It looks like your issue is missing a reproducible example. Please provide a Snack or a repository that demonstrates the issue you are reporting in a minimal, complete, and reproducible manner. |
Hi @000xuandu thanks for the issue. Since this affects iPad, could you provide a repo that demonstrates this issue?
We experienced a similar problem, when a floating keyboard was dismissed the height calculation was off so we ended up with a blank screen (because everything was pushed off the screen).
When the floating keyboard is dismissed we get the following when calculating the relativeKeyboardHeight
keyboardFrame = {screenY: 0, width: 0, screenX: 0, height: 0}
frame = {y: 0, width: 1024, height: 1366, x: 0}
// which gives:
relativeKeyboardHeight 1366
// And therefore pushes all the content all the way to top because the screen height is 1366 on my iPad Pro
We did a workaround to just disable the KeyboardAvoidingView when the keyboard was floating by checking if the keyboard width is the same as the screen width
import { useState, useEffect } from 'react';
import { Keyboard, Dimensions } from 'react-native';
const useIsFloatingKeyboard = () => {
const windowWidth = Dimensions.get('window').width;
const [floating, setFloating] = useState(false);
useEffect(() => {
const onKeyboardWillChangeFrame = (event: KeyboardEvent) => {
setFloating(event.endCoordinates.width !== windowWidth);
};
Keyboard.addListener('keyboardWillChangeFrame', onKeyboardWillChangeFrame);
return () => {
Keyboard.removeListener('keyboardWillChangeFrame', onKeyboardWillChangeFrame);
};
}, [windowWidth]);
return floating;
};
Then in your component
const floating = useIsFloatingKeyboard();
<KeyboardAvoidingView enabled={!floating}>...</KeyboardAvoidingView>
Don't know if the appropriate solution is to disable keyboard avoiding view when the keyboard is floating (as the user can move it wherever) or how to make the component avoid the keyboard when it's moving around.
@Gyran thanks for your workaround!
You probably wanted to removeListener in the return function of useEffect
I refactored it a bit, and designed it as a HOC to replace the original KeyboardAvoidingView
I gonna share the code
import React, { useState, useEffect } from 'react'
import {
Keyboard,
KeyboardAvoidingView as OriginalKeyboardAvoidingView,
Dimensions,
Platform,
} from 'react-native'
export const isIOS = Platform.OS === 'ios'
const useIsFloatingKeyboard = () => {
const [isFloating, setFloating] = useState(false)
const windowWidth = Dimensions.get('window').width
const onKeyboardWillChangeFrame = event => {
setFloating(event.endCoordinates.width !== windowWidth)
}
useEffect(() => {
Keyboard.addListener('keyboardWillChangeFrame', onKeyboardWillChangeFrame)
return () => {
Keyboard.removeListener('keyboardWillChangeFrame', onKeyboardWillChangeFrame)
}
}, [])
return isFloating
}
const KeyboardAvoidingView = ({ children, ...props }) => {
const isFloatingKeyboard = useIsFloatingKeyboard()
return (
<OriginalKeyboardAvoidingView
behavior={isIOS ? 'padding' : 'height'}
enabled={!isFloatingKeyboard}
{...props}
>
{children}
</OriginalKeyboardAvoidingView>
)
}
export default KeyboardAvoidingView
My problem was solved temporarily when I used the library: react-native-keyboard-aware-scroll-view.
Hope to temporarily resolve for you who are experiencing similar errors and wait until the official patch.

@torcoste of course, updated the example with removeListener. Thanks!
Yes KeyboardAvoidingView should be disabled when the keyboard is floating in tablet(iPad)
Created a minimal reproducible example here: https://github.com/Gyran/RNFloatingKeyboardIssue
Would an acceptable solution be to just disable the keyboard avoiding view when a user has a floating keyboard? If so, I could try to implement that in the React Native repo.
We experienced a similar problem, when a floating keyboard was dismissed the height calculation was off so we ended up with a blank screen (because everything was pushed off the screen).
When the floating keyboard is dismissed we get the following when calculating the relativeKeyboardHeight
keyboardFrame = {screenY: 0, width: 0, screenX: 0, height: 0} frame = {y: 0, width: 1024, height: 1366, x: 0} // which gives: relativeKeyboardHeight 1366 // And therefore pushes all the content all the way to top because the screen height is 1366 on my iPad ProWe did a workaround to just disable the KeyboardAvoidingView when the keyboard was floating by checking if the keyboard width is the same as the screen width
import { useState, useEffect } from 'react'; import { Keyboard, Dimensions } from 'react-native'; const useIsFloatingKeyboard = () => { const windowWidth = Dimensions.get('window').width; const [floating, setFloating] = useState(false); useEffect(() => { const onKeyboardWillChangeFrame = (event: KeyboardEvent) => { setFloating(event.endCoordinates.width !== windowWidth); }; Keyboard.addListener('keyboardWillChangeFrame', onKeyboardWillChangeFrame); return () => { Keyboard.removeListener('keyboardWillChangeFrame', onKeyboardWillChangeFrame); }; }, [windowWidth]); return floating; };Then in your component
const floating = useIsFloatingKeyboard(); <KeyboardAvoidingView enabled={!floating}>...</KeyboardAvoidingView>Don't know if the appropriate solution is to disable keyboard avoiding view when the keyboard is floating (as the user can move it wherever) or how to make the component avoid the keyboard when it's moving around.
thanks a lot it works for me!
This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.
This issue was closed because it has been stalled for 7 days with no activity.
Are there any plans to fix this in the built in KeyboardAvoidingView component or do we need to add the suggested logic above ourselves?
Is this issue fixed? We have a problem implementing the suggested logic to all screens in my project.