GithubHelp home page GithubHelp logo

Comments (5)

demchenkoalex avatar demchenkoalex commented on June 9, 2024 1

Hi @lorenzosignoretti,

Thanks for the detailed response. The app looks great 👍

Looking at you sample code, I see that the view with paddingBottom did the job, and good thinking about using bottom inset, there are a lot of different layouts and sometimes it is just needed. You can briefly look through this part of the documentation Handling wrong offsets and you can see that depending on the use case, I recommend using bottom inset among others. You can try mix & match some props I describe in that section, but, in my opinion, your code is fine 🙂

I don't think I can somehow implement this inside the library, because I only have the absolute positioned accessory view and no access to the ScrollView or its parent. Let me know if I need to expose some additional variables, like keyboard open/closed or whatever that might help, but in the end, like I said, I believe this solution is good.

from react-native-keyboard-accessory-view.

lorenzosignoretti avatar lorenzosignoretti commented on June 9, 2024 1

Thanks man, appreciated!

from react-native-keyboard-accessory-view.

demchenkoalex avatar demchenkoalex commented on June 9, 2024

Hello,

Didn't think about this use case and tried to come up with something quickly, but it didn't work for me. I guess this will require some deeper analysis.

from react-native-keyboard-accessory-view.

demchenkoalex avatar demchenkoalex commented on June 9, 2024

Hi, sorry for the late reply.

So I looked at the React Native's KeyboardAvoidingView implementation and I remembered myself that I even used the keyboard subscription logic from the React Native code, so the problem why this library and the KeyboardAvoidingView don't work together is a duplicate logic of subscription to the keyboard events. And then I looked how they realised scrolling to the particular field - they are just adding wrapper view with a paddingBottom - and this library already has the value to past there.

Taken from the docs, basic implementation would look like this

import {
  KeyboardAccessoryView,
  usePanResponder,
} from '@flyerhq/react-native-keyboard-accessory-view'
// ...
const { panHandlers, positionY } = usePanResponder()
const [contentBottomInset, setContentBottomInset] = useState(0)
// ...
return (
  <>
    // Can be anything scrollable
    <ScrollView
      contentContainerStyle={{
        paddingBottom: contentBottomInset,
      }}
      keyboardDismissMode='interactive'
      scrollIndicatorInsets={{ bottom: contentBottomInset }}
      {...panHandlers}
    />
    <KeyboardAccessoryView
      onContentBottomInsetUpdate={setContentBottomInset}
      panResponderPositionY={positionY}
    >
      // Your accessory view
    </KeyboardAccessoryView>
  </>
)

But if we change it to the

import {
  KeyboardAccessoryView,
  usePanResponder,
} from '@flyerhq/react-native-keyboard-accessory-view'
// ...
const { panHandlers, positionY } = usePanResponder()
const [contentBottomInset, setContentBottomInset] = useState(0)
// ...
return (
  <>
    <View style={{ paddingBottom: contentBottomInset }}> // <- add
      // Can be anything scrollable
      <ScrollView
        // contentContainerStyle={{ <- remove
          // paddingBottom: contentBottomInset,
        // }}
        keyboardDismissMode='interactive'
        removeClippedSubviews={false} // <- add if Android keyboard closes instantly
        // scrollIndicatorInsets={{ bottom: contentBottomInset }} <- remove
        {...panHandlers}
      />
    </View> // <- add
    <KeyboardAccessoryView
      onContentBottomInsetUpdate={setContentBottomInset}
      panResponderPositionY={positionY}
    >
      // Your accessory view
    </KeyboardAccessoryView>
  </>
)

the result will be

Screen Recording 2020-09-11 at 18 31 23

This is also works on Android, but on Android I noticed keyboard opens and closes instantly when you select an input which will need to be avoided, this prop on a scroll view helped removeClippedSubviews={false}.

Let me know if that helps, and I will add it to the docs, if it is.

from react-native-keyboard-accessory-view.

lorenzosignoretti avatar lorenzosignoretti commented on June 9, 2024

Hi @demchenkoalex, I tried your solution but I had to find a different workaround to get everything working as intended.

In a gist, I needed to implement the KeyboardAccessoryView on a Screen that has a custom header. In addition, I wanted to display KeyboardAccessoryView programmatically when a certain Row was on focus (not persistently in view). Finally, the children of KeyboardAccessoryView were descendants of a different components tree (I ended up using a react-native-portal to achieve this, but you could easily create your own implementation using React's context).

I am quite pleased with the final result (the video is a bit choppy because of my development machine):
appVideo

Here is how the structure of my project ended up in a nutshell:

import {
  KeyboardAccessoryView,
  usePanResponder,
} from '@flyerhq/react-native-keyboard-accessory-view'
import {useSafeAreaInsets} from 'react-native-safe-area-context';
// ...
const { panHandlers, positionY } = usePanResponder()
const [contentBottomInset, setContentBottomInset] = useState(0)
const insets = useSafeAreaInsets();
// ...
return (
  <>
    <CustomHeader/>
      <View style={{flex: 1}}>
        <View
          style={{
            flexGrow: 1,
            paddingBottom: contentBottomInset + insets.bottom,
          }}>
          <ScrollView
            style={{flexGrow: 1}}
            keyboardDismissMode="interactive"
            showsVerticalScrollIndicator={false}
            {...panHandlers}>
            // ScrollView content (including component responsible for rendering the contents of the keyboard-accessory-view-portal)
          </ScrollView>
        </View>
        <KeyboardAccessoryView
          onContentBottomInsetUpdate={setContentBottomInset}
          panResponderPositionY={positionY}>
          <WhitePortal name="keyboard-accessory-view-portal">
          // Your accessory view
          </WhitePortal>
        </KeyboardAccessoryView>
      </View>
  </>
)

As you can see, there are lots of insets to take into account to make sure everything displays correctly.

The current implementation works quite well, but I'm not sure I'm fully happy with the structure of the code. Looking forward to hear from you if you would have solved this in a simpler way.

So far, I tested it on iOS only and it works perfectly.

from react-native-keyboard-accessory-view.

Related Issues (14)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.