react-native icon indicating copy to clipboard operation
react-native copied to clipboard

The keyboard in floating mode is having problem.

Open 000xuandu opened this issue 5 years ago • 10 comments

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. image

Screen capture when the keyboard is in floating mode. image

Code: image

000xuandu avatar Jul 23 '20 07:07 000xuandu

: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.

github-actions[bot] avatar Aug 05 '20 17:08 github-actions[bot]

Hi @000xuandu thanks for the issue. Since this affects iPad, could you provide a repo that demonstrates this issue?

safaiyeh avatar Aug 05 '20 17:08 safaiyeh

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 avatar Sep 22 '20 11:09 Gyran

@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

torcoste avatar Oct 03 '20 13:10 torcoste

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.

image

000xuandu avatar Oct 06 '20 02:10 000xuandu

@torcoste of course, updated the example with removeListener. Thanks!

Gyran avatar Oct 06 '20 05:10 Gyran

Yes KeyboardAvoidingView should be disabled when the keyboard is floating in tablet(iPad)

mym0404 avatar Jan 21 '21 03:01 mym0404

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.

Gyran avatar Mar 04 '21 15:03 Gyran

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.

thanks a lot it works for me!

luism3861 avatar Nov 24 '21 18:11 luism3861

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.

github-actions[bot] avatar Jun 15 '23 05:06 github-actions[bot]

This issue was closed because it has been stalled for 7 days with no activity.

github-actions[bot] avatar Jun 22 '23 05:06 github-actions[bot]

Are there any plans to fix this in the built in KeyboardAvoidingView component or do we need to add the suggested logic above ourselves?

mattaningram avatar Mar 05 '24 17:03 mattaningram

Is this issue fixed? We have a problem implementing the suggested logic to all screens in my project.

gkasireddy202 avatar Apr 18 '24 09:04 gkasireddy202