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.54k stars 61 forks source link

[iOS] Modal + KeyboardToolbar = incorrect arrows state #510

Closed jurawrssic closed 1 month ago

jurawrssic commented 1 month ago

Describe the bug Hi, I'm running into this issue where the arrows don't seem to behave as expected. Given a form with only 2 inputs enabled I see the following behavior:

So, my question here is: is there a way I can specify the ammount of inputs on my screen or maybe the order that they should be detected?

Code snippet I cannot add a code snippet due to NDA, I know my issue might not contain enough information but we can go back and forth with solutions.

Repo for reproducing

To Reproduce

Expected behavior I expected the arrows to behave accordingly to the docs following the view tree.

Screenshots

Screenshot 2024-07-17 at 12 56 19

Smartphone (please complete the following information):

Additional context

jurawrssic commented 1 month ago

Looking further into this it seems that the inputs state for me is always { count: 0, current: 0 } and then { count: -1, current: 0}

kirillzyusko commented 1 month ago

@jurawrssic do you have inputs behind the modal? Can you try to use the latest version of the library?

Can you provide a minimal reproduction example?

This is really strange why inputs are not getting detected. Is it iOS only specific problem?

jurawrssic commented 1 month ago

@kirillzyusko hi! Thanks for getting back to me on this.

I'll see if I can provide a reproduction example.

So I was messing around your code and if I remove the disabling of the arrow buttons, they jump to each input just fine, it seems that the problem is located at the logic part of disabling/enabling arrows, like you said, seems like the inputs aren't being recognized but I don't really know Swift to dig much further.

kirillzyusko commented 1 month ago

@jurawrssic I think I reproduced a problem:

I used next code:

import { BlurView } from "@react-native-community/blur";
import React, { useCallback, useState } from "react";
import { Button, Modal, Platform, StyleSheet, View } from "react-native";
import { trigger } from "react-native-haptic-feedback";
import {
  KeyboardAwareScrollView,
  KeyboardToolbar,
} from "react-native-keyboard-controller";

import TextInput from "../../../components/TextInput";

import AutoFillContacts from "./Contacts";

import type { Contact } from "./Contacts";

// Optional configuration
const options = {
  enableVibrateFallback: true,
  ignoreAndroidSystemSettings: false,
};
const haptic = () =>
  trigger(Platform.OS === "ios" ? "impactLight" : "keyboardTap", options);

export default function ToolbarExample() {
  const [showAutoFill, setShowAutoFill] = useState(false);
  const [name, setName] = useState("");
  const onContactSelected = useCallback((contact: Contact) => {
    setName(contact.name);
  }, []);
  const onShowAutoFill = useCallback(() => {
    setShowAutoFill(true);
  }, []);
  const onHideAutoFill = useCallback(() => {
    setShowAutoFill(false);
  }, []);

  const [isVisible, setVisible] = useState(false);

  return (
    <>
      <Button title="Show modal" onPress={() => setVisible(true)} />
      <Modal visible={isVisible} presentationStyle="formSheet" animationType="slide" onRequestClose={() => setVisible(false)}>
        <KeyboardAwareScrollView
          bottomOffset={62}
          style={[styles.withPadding, styles.container]}
          testID="toolbar.scrollView"
        >
          <TextInput
            keyboardType="default"
            placeholder="Your name"
            title="Name"
            testID="TextInput#1"
            onFocus={onShowAutoFill}
            defaultValue={name}
          />
          <TextInput
            keyboardType="default"
            placeholder="Your surname"
            title="Surname"
            testID="TextInput#2"
            onFocus={onHideAutoFill}
            multiline={false}
          />
          <TextInput
            keyboardType="default"
            placeholder="example@gmail.com"
            title="Email"
            editable={false}
            multiline={false}
            onFocus={onHideAutoFill}
            testID="TextInput#3"
          />
          <TextInput
            keyboardType="default"
            placeholder="Tell us funny facts about you"
            title="About you"
            editable={false}
            onFocus={onHideAutoFill}
            testID="TextInput#4"
          />
          <View style={styles.row}>
            <View style={styles.birthday}>
              <TextInput
                keyboardType="numeric"
                multiline={false}
                placeholder="DD"
                title="Day"
                onFocus={onHideAutoFill}
                testID="TextInput#5"
              />
            </View>
            <View style={[styles.birthday, styles.withPadding]}>
              <TextInput
                keyboardType="numeric"
                multiline={false}
                placeholder="MM"
                title="Month"
                onFocus={onHideAutoFill}
                testID="TextInput#6"
              />
            </View>
            <View style={styles.birthday}>
              <TextInput
                keyboardType="numeric"
                multiline={false}
                placeholder="YYYY"
                title="Year"
                onFocus={onHideAutoFill}
                testID="TextInput#7"
              />
            </View>
          </View>
          <TextInput
            keyboardType="default"
            placeholder="Country"
            title="Country"
            onFocus={onHideAutoFill}
            testID="TextInput#8"
          />
          <TextInput
            keyboardType="default"
            placeholder="Region of the city"
            title="Region"
            onFocus={onHideAutoFill}
            testID="TextInput#9"
          />
          <TextInput
            keyboardType="default"
            placeholder="City where you currently live"
            title="City"
            onFocus={onHideAutoFill}
            testID="TextInput#10"
          />
          <TextInput
            keyboardType="default"
            placeholder="Street name"
            title="Street"
            onFocus={onHideAutoFill}
            testID="TextInput#11"
          />
          <TextInput
            contextMenuHidden
            keyboardType="numeric"
            placeholder="House number"
            title="House"
            onFocus={onHideAutoFill}
            testID="TextInput#12"
          />
          <TextInput
            contextMenuHidden
            keyboardType="numeric"
            placeholder="Flat number"
            title="Flat"
            onFocus={onHideAutoFill}
            testID="TextInput#13"
          />
        </KeyboardAwareScrollView>
        <KeyboardToolbar
          content={
            showAutoFill ? (
              <AutoFillContacts onContactSelected={onContactSelected} />
            ) : null
          }
          blur={blur}
          opacity={Platform.OS === "ios" ? "4F" : "DD"}
          onDoneCallback={haptic}
          onPrevCallback={haptic}
          onNextCallback={haptic}
        />
      </Modal>
    </>
  );
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: "white",
  },
  row: {
    flexDirection: "row",
  },
  birthday: {
    flex: 1 / 3,
  },
  withPadding: {
    paddingHorizontal: 16,
  },
  absolute: {
    position: "absolute",
    top: 0,
    left: 0,
    bottom: 0,
    right: 0,
  },
});

const blur = (
  <BlurView
    blurType={Platform.OS === "ios" ? "chromeMaterial" : "light"}
    blurAmount={32}
    reducedTransparencyFallbackColor="white"
    style={styles.absolute}
  />
);

I'll try to see where is the problem 👀

jurawrssic commented 1 month ago

@kirillzyusko Super cool you were able to reproduce this with bare minimum info! You rock! So it seems that the issue is happening due to the modal/bottom sheet? Hopefully you're able to find out what's going on! 🤞

kirillzyusko commented 1 month ago

@jurawrssic yeah, can you check if https://github.com/kirillzyusko/react-native-keyboard-controller/pull/514 fixes the problem? In my case it started to work properly 😊 Curious to know if it fixes problem for you too or not 👀

jurawrssic commented 1 month ago

Hey @kirillzyusko, that works! Awesome! Thank you so much 😄

jurawrssic commented 1 month ago

Hey @kirillzyusko, just checking in, was this fix not included in the latest release?

kirillzyusko commented 1 month ago

@jurawrssic hm, it should be included in 1.12.7 🤔

Did you update to the latest version (1.12.7) and the issue is still there?..

jurawrssic commented 4 weeks ago

Hey @kirillzyusko, nevermind, it works! I think it was some cache related issue not sure, when I first checked it didn't work but after re running everything the solution is working, thank you.

kirillzyusko commented 4 weeks ago

Glad to know that it works 😊