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

TextInput does not stick in the right place with KeyboardAvoidingView and ScrollView #402

Closed irekrog closed 3 months ago

irekrog commented 6 months ago

Describe the bug When the content is scrolled to the bottom, halfway down the screen, etc., and the input is pressed, it is not always properly sticked and visible

Code snippet

import React from "react";
import {
  Button,
  Image,
  Text,
  TextInput,
  View,
} from "react-native";
import {
  KeyboardAvoidingView, KeyboardStickyView,
  useReanimatedKeyboardAnimation
} from "react-native-keyboard-controller";

import styles from "./styles";

import {ScrollView} from "react-native-gesture-handler";
import Animated, {useAnimatedStyle} from "react-native-reanimated";

export default function KeyboardAvoidingViewExample() {
  const {progress, height} = useReanimatedKeyboardAnimation();

  const animatedWrapperStyles = useAnimatedStyle(() => ({
    transform: [
      {
        translateY: progress.value ? -400 : 0,
      },
    ],
  }));

  return (
    <View style={{flex: 1}}>
      <KeyboardAvoidingView style={{flex: 1}}>
        <ScrollView style={{flex: 1}}>
          <Animated.View style={[
            animatedWrapperStyles,
            {flex: 1},
          ]}>
            <Image
              style={{width: 400, height: 400}}
              source={{
                uri: 'https://reactnative.dev/img/tiny_logo.png',
              }}
            />
            <View>
              <TextInput
                placeholder="Username"
                placeholderTextColor="#7C7C7C"
                style={styles.textInput}
              />
              <TextInput
                placeholder="Password"
                placeholderTextColor="#7C7C7C"
                style={styles.textInput}
                secureTextEntry
              />
            </View>
            <View>
              <Text>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
                dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
                ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
                fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
                deserunt mollit anim id est laborum.

              </Text>
              <Text>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
                dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
                ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
                fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
                deserunt mollit anim id est laborum.
              </Text>
              <Text>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
                dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
                ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
                fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
                deserunt mollit anim id est laborum.
              </Text>
              <Text>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
                dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
                ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
                fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
                deserunt mollit anim id est laborum.
              </Text>
              <Text>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
                dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
                ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
                fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
                deserunt mollit anim id est laborum.
              </Text>
            </View>
          </Animated.View>
        </ScrollView>
      </KeyboardAvoidingView>
      <KeyboardStickyView offset={{
        closed: 0,
        opened: -5,
      }}>
        <Button title={"Submit"} onPress={() => {}} />
      </KeyboardStickyView>
    </View>
  );
}

Repo for reproducing You can paste a code above to src/screens/Examples/KeyboardAvoidingView/index.tsx in this repo

Expected behavior TextInput should stick to the right place

Screenshots

https://github.com/kirillzyusko/react-native-keyboard-controller/assets/11172548/d970e901-b37e-4aae-9ec7-bafb3a35d828

Smartphone

kirillzyusko commented 6 months ago

Hey @irekrog

I think this is kind of expected behavior, since KeyboardAvoidingView is designed to simply resize container without paying an attention to TextInput position (correct me if I'm wrong)?.. What is the behavior of KeyboardAvoidingView from RN on iOS? πŸ‘€ Does it have the same problem or not?

In your layout I think I'd recommend to use KeyboardAwareScrollView (because according to description you want to achieve the effect provided by this component).

Plus I see that additionally you are moving your content by 400px (which is also not sensitive to focused TextInput position (i. e. if you scrolled and your input around top of the screen -> you still move the view by 400px and thus the input gets hidden)).

irekrog commented 6 months ago

What is the behavior of KeyboardAvoidingView from RN on iOS? πŸ‘€ Does it have the same problem or not?

On iOS it looks a much better, so I'm not sure what is wrong πŸ˜•

https://github.com/kirillzyusko/react-native-keyboard-controller/assets/11172548/7de3240d-c642-4760-930d-daf914538bce

Plus I see that additionally you are moving your content by 400px

Yes, because I want to hide the image outside a screen window when keyboard is active. Exactly like on this recorded video from iPhone.

irekrog commented 6 months ago

@kirillzyusko and I'm trying to use KeyboardAwareScrollView but there is no difference

kirillzyusko commented 6 months ago

@irekrog what happens here:

image

I don't see a keyboard, but according to Submit button it's kind of visible?

irekrog commented 6 months ago

@kirillzyusko yep, it's a problem with recorded video because actually there is a keyboard

kirillzyusko commented 6 months ago

Yes, because I want to hide the image outside a screen window when keyboard is active. Exactly like on this recorded video from iPhone.

I don't know why iPhone behaves in this way, but on the layout that you provided:

Maybe because of layout animations (or some internal stuff inside) iOS itself does a little bit magic and changes view positions to what you expect, but on Android it'll not work for sure I think.

I'll test your layout when I have time (but can not promise it'll be soon, because I have a plenty of work with keyboard controller at the moment πŸ˜…)

And yeah, last but not least - you can create your own avoiding solution that will be specific for your layout:

Using all these variables you'll be able to calculate necessary layout adjustments.

and I'm trying to use KeyboardAwareScrollView but there is no difference

Can you share a code sample with KeyboardAwareScrollView?

I think KeyboardAwareScrollView with bottomOffset should do a trick. Also I can recommend you to try to change size of your image (set height to 0 when keyboard is open), instead of translation entire ScrollView content.

irekrog commented 6 months ago

Sure I'll try, and thanks for tips :)

Can you share a code sample with KeyboardAwareScrollView?

Nothing special, I just changed component from KeyboardAvoidingView to KeyboardAwareScrollView and tried manipulate bottomOffset but behavior is similar like on the attached video.

kirillzyusko commented 6 months ago

Nothing special, I just changed component from KeyboardAvoidingView to KeyboardAwareScrollView and tried manipulate bottomOffset but behavior similar like on the attached video.

Okay, got you! Then I think the problem happens because of these additional 400px translation - potentially resizing content (changing real layout) may fix the problem, but of course need to try πŸ™‚

Feel free to share your observations here - I'll try to help if I can πŸ˜…

kirillzyusko commented 3 months ago

@irekrog I'm going to close this issue. I hope I provided the answer on how to achieve desired behavior ☺️

Maybe in future this library will be able to synchronously retrieve a layout of focused input in each keyboard frame, and your use case will work out of the box πŸ‘