Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The keyboard in floating mode is having problem. #29473

Closed
000xuandu opened this issue Jul 23, 2020 · 13 comments
Closed

The keyboard in floating mode is having problem. #29473

000xuandu opened this issue Jul 23, 2020 · 13 comments
Labels
Component: KeyboardAvoidingView Needs: Attention Issues where the author has responded to feedback. Needs: Issue Manager Attention Needs: Repro This issue could be improved with a clear list of steps to reproduce the issue. Stale There has been a lack of activity on this issue and it may be closed soon.

Comments

@000xuandu
Copy link

000xuandu commented Jul 23, 2020

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

@safaiyeh safaiyeh added Component: KeyboardAvoidingView Needs: Repro This issue could be improved with a clear list of steps to reproduce the issue. and removed API: Keyboard Needs: Triage 🔍 labels Aug 5, 2020
@github-actions
Copy link

github-actions bot commented Aug 5, 2020

⚠️ Missing Reproducible Example
ℹ️ 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.

@safaiyeh
Copy link
Contributor

safaiyeh commented Aug 5, 2020

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

@Gyran
Copy link
Contributor

Gyran commented Sep 22, 2020

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.

@torcoste
Copy link

torcoste commented Oct 3, 2020

@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

@000xuandu
Copy link
Author

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

@github-actions github-actions bot added Needs: Attention Issues where the author has responded to feedback. and removed Needs: Author Feedback labels Oct 6, 2020
@Gyran
Copy link
Contributor

Gyran commented Oct 6, 2020

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

@mym0404
Copy link
Contributor

mym0404 commented Jan 21, 2021

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

@Gyran
Copy link
Contributor

Gyran commented Mar 4, 2021

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.

@luism3861
Copy link
Contributor

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!

@github-actions
Copy link

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 github-actions bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Jun 15, 2023
@github-actions
Copy link

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

@mattaningram
Copy link

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

@gkasireddy202
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: KeyboardAvoidingView Needs: Attention Issues where the author has responded to feedback. Needs: Issue Manager Attention Needs: Repro This issue could be improved with a clear list of steps to reproduce the issue. Stale There has been a lack of activity on this issue and it may be closed soon.
Projects
None yet
Development

No branches or pull requests

9 participants