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

IOS: KeyboardToolbar does not respect safe area in landscape orientation #572

Open
nullatnothing opened this issue Aug 30, 2024 · 4 comments
Assignees
Labels
🐛 bug Something isn't working 🍎 iOS iOS specific KeyboardToolbar Anything related to KeyboardToolbar component

Comments

@nullatnothing
Copy link

nullatnothing commented Aug 30, 2024

Describe the bug
On IOS devices in landscape orientation the "up arrow" button on the left and the "Close" button on the right are outside the safe area and covered by the "isle" (front camera on iPhone 15).

Code snippet
The error occurs in the file: src/components/KeyboardToolbar/index.tsx
at line: 216

Here the code:

const styles = StyleSheet.create({
  flex: {
    flex: 1,
  },
 toolbar: {
    position: "absolute",
    bottom: 0,
    alignItems: "center",
    width: "100%",
    flexDirection: "row",
    height: KEYBOARD_TOOLBAR_HEIGHT,
    paddingHorizontal: 8, **<-- HERE THE BUG**
  },

The paddingHorizontal is declared as constant with a value of 8. On IOS it's required to be dynamic to adapt to safe area padding.

Repo for reproducing
Create a component with following code:

import React from 'react';
import {View, SafeAreaView} from 'react-native';
import {
KeyboardAwareScrollView,
KeyboardToolbar,
} from 'react-native-keyboard-controller';

const FailingScreen = props => {

return (
	<>
	  <SafeAreaView
		<KeyboardAwareScrollView>
			<Text>{'INPUT'}</Text>
			<TextInput />
		</KeyboardAwareScrollView>
	  </MODSafeAreaView>
	  <KeyboardToolbar doneText={'EXIT'} />
	</>
  );
};

export default FailingScreen;

To Reproduce
Steps to reproduce the behavior:

  1. Create app with above component
  2. Run app on IOS device/simulator (eg. iPhone 15)
  3. Tap on TextInput to open the keyboard
  4. Rotate device/simulator
  5. See error

Expected behavior
The "up arrow" button on the left and the "Close" button on the right to be within the safe area and not covered by the "isle" (front camera on iPhone 15).

Smartphone (please complete the following information):

  • Desktop OS: [MacOS 14.6.1]
  • Device: [iPhone 15]
  • OS: [iOS 17.5]
  • RN version: [0.74.5]
  • RN architecture: [old]
  • JS engine: [Hermes]
  • Library version: [1.13.3]

Additional context
I patched the file: src/components/KeyboardToolbar/index.tsx

with following code:

import { Platform, StyleSheet, Text, View } from "react-native";
import {useSafeAreaInsets} from 'react-native-safe-area-context';
....
const insets = useSafeAreaInsets();
....
const toolbarStyle = useMemo(
    () => [
      styles.toolbar,
      {
        paddingLeft: Platform.OS === 'ios' ? insets.left + 8 : 8,
        paddingRight: Platform.OS === 'ios' ? insets.right  + 8 : 8,
        backgroundColor: `${theme[colorScheme].background}${opacity}`,
      },
    ],
    [colorScheme, opacity, theme, insets],
  );
....
@kirillzyusko kirillzyusko added 🍎 iOS iOS specific KeyboardToolbar Anything related to KeyboardToolbar component labels Aug 30, 2024
@kirillzyusko
Copy link
Owner

@nullatnothing are you referring to this bug, right?

image

@kirillzyusko kirillzyusko added the 🐛 bug Something isn't working label Aug 30, 2024
@nullatnothing
Copy link
Author

Yes

@kirillzyusko
Copy link
Owner

@nullatnothing maybe you know ways how to fix that without using react-native-safe-area-context? 😅

The reason why I'm asking is because I don't want to depend on another library and want to have as less as possible external dependencies. I've tried to use SafeAreaView from react-native but it doesn't give a satisfactory results 😔

@nullatnothing
Copy link
Author

nullatnothing commented Sep 4, 2024

@kirillzyusko I've tried all other available modules / views etc. but the only one, that works, is useSafeAreaInsets() from react-native-safe-area-context.

An approach could be following:

  • get insets on the native side
  • expose the values to RN

Here an example:

extension UIApplication { static var insets: UIEdgeInsets { let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene return scene?.windows.first?.safeAreaInsets ?? .zero } }

Here the docs for native safe area insets.

Here is the approach used by RNSafeAreaContext

I've found, that you already have a reference to UIApplication.shared.keyWindow in the file UIApplication.swift at line 13.

The implementation could be:

static var insets: UIEdgeInsets { return UIApplication.shared.keyWindow?.safeAreaInsets ?? .zero }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐛 bug Something isn't working 🍎 iOS iOS specific KeyboardToolbar Anything related to KeyboardToolbar component
Projects
None yet
Development

No branches or pull requests

2 participants