kirillzyusko / react-native-keyboard-controller

Keyboard manager which works in identical way on both iOS and Android
https://kirillzyusko.github.io/react-native-keyboard-controller/
MIT License
1.62k stars 67 forks source link

KeyboardAwareScrollView doesn't work as expected on IOS #453

Closed byazamat closed 4 months ago

byazamat commented 4 months ago

Describe the bug First of all, I want to thank you for this awesome library. When the keyboard is in a closed state and I focus on one of the last inputs, the keyboard overlaps the input, so KeyboardAwareScrollView doesn't work as expected. However, if I focus step by step from the first input to the last input, it works perfectly. This issue only occurs on iOS, on Android, it works as expected.

Additionally, when the app is opened from a closed state and any input is pressed, it takes time to focus (you can see this in the video that I provided below). This doesn't seem to have happened before installing the library.

Steps that I have done to start work with the library

Please, can you help me to find the problem? I didn't find issues like mine. I don't understand what I did wrong. I would be really appreciative of your assistance.

Code snippet

import React, {useState} from 'react';
import {SafeAreaView, StyleSheet, Text, TextInput, View} from 'react-native';
import {
  KeyboardAwareScrollView,
  KeyboardProvider,
} from 'react-native-keyboard-controller';

type FormSchema = {
  username: string;
  firstname: string;
  lastname: string;
  email: string;
  addressOne: string;
  addressTwo: string;
  phoneNumber: string;
  promoCode: string;
  message: string;
  comment: string;
};

type FormKey = keyof FormSchema;

function App(): React.JSX.Element {
  const [form, setForm] = useState<FormSchema>({
    username: '',
    firstname: '',
    lastname: '',
    email: '',
    addressOne: '',
    addressTwo: '',
    phoneNumber: '',
    promoCode: '',
    message: '',
    comment: '',
  });

  const changeFormChange = (key: FormKey, value: string) => {
    setForm(prev => ({...prev, [key]: value}));
  };

  return (
    <KeyboardProvider>
      <SafeAreaView style={styles.container}>
        <KeyboardAwareScrollView
          bottomOffset={50}
          style={styles.container}
          contentContainerStyle={styles.content}>
          <Text style={styles.heading}>Keyboard Aware ScrollView</Text>
          <TextInput
            style={styles.input}
            value={form.username}
            placeholder="Username"
            placeholderTextColor="#747474"
            testID={`TextInput#Username`}
            onChangeText={value => changeFormChange('username', value)}
          />
          <TextInput
            style={styles.input}
            value={form.firstname}
            placeholder="Firstname"
            placeholderTextColor="#747474"
            testID={`TextInput#Firstname`}
            onChangeText={value => changeFormChange('firstname', value)}
          />
          <TextInput
            style={styles.input}
            value={form.lastname}
            placeholder="Lastname"
            placeholderTextColor="#747474"
            testID={`TextInput#Lastname`}
            onChangeText={value => changeFormChange('lastname', value)}
          />
          <TextInput
            style={styles.input}
            value={form.email}
            placeholder="Email"
            placeholderTextColor="#747474"
            testID={`TextInput#Email`}
            onChangeText={value => changeFormChange('email', value)}
          />
          <TextInput
            style={styles.input}
            value={form.addressOne}
            placeholder="Address 1"
            placeholderTextColor="#747474"
            testID={`TextInput#Address`}
            onChangeText={value => changeFormChange('addressOne', value)}
          />
          <TextInput
            style={styles.input}
            value={form.addressTwo}
            placeholder="Address 2"
            placeholderTextColor="#747474"
            testID={`TextInput#Address`}
            onChangeText={value => changeFormChange('addressTwo', value)}
          />
          <TextInput
            style={styles.input}
            value={form.phoneNumber}
            placeholder="Phone number"
            placeholderTextColor="#747474"
            testID={`TextInput#Phone`}
            onChangeText={value => changeFormChange('phoneNumber', value)}
          />
          <TextInput
            style={styles.input}
            value={form.message}
            placeholder="Message"
            placeholderTextColor="#747474"
            testID={`TextInput#Message`}
            onChangeText={value => changeFormChange('message', value)}
          />
          <TextInput
            style={styles.input}
            value={form.comment}
            placeholder="Comment"
            placeholderTextColor="#747474"
            testID={`TextInput#Comment`}
            onChangeText={value => changeFormChange('comment', value)}
          />
        </KeyboardAwareScrollView>
      </SafeAreaView>
    </KeyboardProvider>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
  },
  heading: {
    fontSize: 36,
    fontWeight: '800',
    marginBottom: 8,
    color: '#000',
  },
  content: {
    padding: 16,
    gap: 8,
  },
  input: {
    height: 48,
    borderRadius: 12,
    paddingHorizontal: 12,
    backgroundColor: '#fafafa',
    borderWidth: 1,
    borderColor: '#dddddd',
    color: '#000',
  },
});

export default App;

Repo for reproducing Here is the minimal repo: GitHub Repo

To Reproduce Steps to reproduce the behavior:

  1. Run yarn run ios
  2. Press on last input
  3. See problem with overlap

Expected behavior I think KeyboardAwareScrollView should scroll to the focused input like on Android (you can see this in the video that I provided below).

Screenshots IOS (With problem) https://github.com/kirillzyusko/react-native-keyboard-controller/assets/77745661/e42b0fb8-4429-4ec7-b8ec-d3f2a44077c8 Android https://github.com/kirillzyusko/react-native-keyboard-controller/assets/77745661/1b307f3c-1f5e-4287-b93a-575c682233ca

Smartphone (please complete the following information):

kirillzyusko commented 4 months ago

Hey @byazamat

Thank you for the report! I'll have a look on why it doesn't work! 👀

kirillzyusko commented 4 months ago

Okay, parentScrollViewTarget=-1 because of that we skip scrolling. It resolves to -1 because it gets detected as a horizontal ScrollView:

image

I added this condition in this PR: https://github.com/kirillzyusko/react-native-keyboard-controller/pull/443

Seems like I need to find a better way of detection horizontal/vertical ScrollView 👀

kirillzyusko commented 4 months ago

@byazamat can you check if https://github.com/kirillzyusko/react-native-keyboard-controller/pull/454 fixes the problem?

byazamat commented 4 months ago

@byazamat can you check if #454 fixes the problem?

It seems that this has resolved the problem.

https://github.com/kirillzyusko/react-native-keyboard-controller/assets/77745661/81c12237-82bd-4995-b657-424ea6a98829

Thanks for your quick response!

kirillzyusko commented 4 months ago

@byazamat I merged a PR, but don't know yet when I publish a new version. You can use patch-package and apply a patch with this fix in your project 👀

byazamat commented 4 months ago

I will be eagerly looking forward to the new version. In the meantime, the patch is the optimal solution. @kirillzyusko I am very grateful for your hard work! 🫡