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

Add animatedKeyboardHeight in useKeyboard hook #140

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

magrinj
Copy link

@magrinj magrinj commented Apr 9, 2020

Summary

In order to animate properly based on the keyboard apparition, this PR add a new value in useKeyboard hook called animatedKeyboardHeight.
It also add a new hook useAnimatedValue that just wrap the Animated.Value into a useRef hook.

Solve #81

Test Plan

import { useKeyboard } from '@react-native-community/hooks'

const keyboard = useKeyboard()
<Animated.View style={{height: keyboard.animatedKeyboardHeight}} />

Compatibility

OS Implemented
iOS
Android
Web

Checklist

README.md Outdated Show resolved Hide resolved
Co-Authored-By: Linus Unnebäck <[email protected]>
@LinusU
Copy link
Member

LinusU commented Apr 9, 2020

This looks great! Would love to see a Snack posted so that I can try it out ☺️

Currently it doesn't seem to handle when the keyboard changes height? 🤔 e.g. when switching between emoji and text input

@magrinj
Copy link
Author

magrinj commented Apr 9, 2020

This looks great! Would love to see a Snack posted so that I can try it out ☺️

Currently it doesn't seem to handle when the keyboard changes height? 🤔 e.g. when switching between emoji and text input

You can find the snack just here: https://snack.expo.io/@magrin_j/usekeyboard-animatedkeyboardheight

It's actually working even if the keyboard height change when switching between classic keyboard and emoji by example. In the snack I've added an extra 150ms duration in the animation because when it's a switch between two kind of keyboard the duration is set to 0, what do you think about that, we should actually put a default duration no ?

@LinusU
Copy link
Member

LinusU commented Apr 10, 2020

It's actually working even if the keyboard height change when switching between classic keyboard and emoji by example. In the snack I've added an extra 150ms duration in the animation because when it's a switch between two kind of keyboard the duration is set to 0, what do you think about that, we should actually put a default duration no ?

Since the keyboard itself isn't animated when we are switching between different layouts, I think that the duration should stay as 0 in those cases.

I think that an important use case that should be addressed by this is having a view that spans the entire screen, but doesn't get covered by the keyboard. The goal here is that the view should always be the exact space visible over the keyboard and thus it's important that the durations are exactly the same as how the keyboard moves.

If we added an extra duration, elements would be partially covered by the keyboard when switching to a higher layout, and then they would animate up from under the keyboard. Since the OS doesn't have an animation when switching layouts, I don't think we should either ☺️

I've modified the Snack slightly here to show what I mean:

https://snack.expo.io/@linusu/usekeyboard-animatedkeyboardheight-linusu

As you can see it is almost perfect, it's just the easing curves that are off a bit (at least on iOS, haven't had time to test Android yet).

Frame 0 Frame 1 Frame 2
Frame 8 Frame 9 Frame 10
Frame 11 Frame 12 Frame 13
Frame 24 Frame 25 Frame 26

I know that this might be crazy levels of attention to details 😂 but I would really like to get this within a few pixels of right so that it looks really nice for the app I'm currently working on!

@LinusU
Copy link
Member

LinusU commented Apr 10, 2020

Okay, I have all the points now, I just need to figure out the curve to produce them 😁

Frame Pixels
0 0
1 93
2 279
3 371
4 456
5 531
6 595
7 649
8 694
9 733
10 761
11 785
12 818
13 830
14 840
15 846
16 852
17 858
18 864
19 866
20 868
21 868
22 870
23 870
24 872
25 872
26 873

@magrinj
Copy link
Author

magrinj commented Apr 10, 2020

It's actually working even if the keyboard height change when switching between classic keyboard and emoji by example. In the snack I've added an extra 150ms duration in the animation because when it's a switch between two kind of keyboard the duration is set to 0, what do you think about that, we should actually put a default duration no ?

Since the keyboard itself isn't animated when we are switching between different layouts, I think that the duration should stay as 0 in those cases.

I think that an important use case that should be addressed by this is having a view that spans the entire screen, but doesn't get covered by the keyboard. The goal here is that the view should always be the exact space visible over the keyboard and thus it's important that the durations are exactly the same as how the keyboard moves.

If we added an extra duration, elements would be partially covered by the keyboard when switching to a higher layout, and then they would animate up from under the keyboard. Since the OS doesn't have an animation when switching layouts, I don't think we should either ☺️

I've modified the Snack slightly here to show what I mean:

https://snack.expo.io/@linusu/usekeyboard-animatedkeyboardheight-linusu

As you can see it is almost perfect, it's just the easing curves that are off a bit (at least on iOS, haven't had time to test Android yet).

I know that this might be crazy levels of attention to details 😂 but I would really like to get this within a few pixels of right so that it looks really nice for the app I'm currently working on!

Ok, you're right, it's better to keep the duration to 0 as it's not animated during the switch 🙂

For the easing curve, I guess we can take a look of what's using natively to produce the animation, like Easing.linear or something else, changing this could solve the issue, or if not we can create an interpolation array to produce a new output that exactly match the keyboard.

@magrinj
Copy link
Author

magrinj commented Apr 10, 2020

@LinusU
Copy link
Member

LinusU commented Apr 11, 2020

Ahh, cool, I've never heard of LayoutAnimation before, interesting. It seems like it's experimental on Android though 😅

I managed to create a very close beizer curve by simply overlaying a plot of the values I collected and playing with the knobs 😄

Screenshot_2020-04-10_at_13 45 52

But for some reason the duration of the animation simply isn't correct 🤔 I have to add 167ms in order for the durations to match, and I cannot figure out why 😫

@magrinj
Copy link
Author

magrinj commented Apr 11, 2020

@LinusU Yes, it’s actually still experimental on Android, and it’s not working with Animated.Value from what I’ve understood.
The animation is triggered for the next render with LayoutAnimation.

Really strange for the extra duration as without, it actually match time. Not the curve, but the time should be fine 😕

When you’ve done your screenshot and to estimate the frame and height, did you enable the slow animation mode ? If so, the duration will not match as it’s slowed

@LinusU
Copy link
Member

LinusU commented Apr 12, 2020

When you’ve done your screenshot and to estimate the frame and height, did you enable the slow animation mode ? If so, the duration will not match as it’s slowed

Yes I tried running in slow mode, the problem is that the duration is still reported as 250ms in slow mode so I couldn't match my animation with that one automatically.

I would really like to know the slow down factor as it would help me debugging the delay issue. If I multiply the duration by 20x, the duration seem to match perfectly when running in slow mode without me adding the extra duration. If I multiply by 12x and also add 12x my extra duration, everything also matches up.

When running in normal mode, both in simulator and on device, I need the to add the extra duration in order for the animations to match 😕

@magrinj
Copy link
Author

magrinj commented Apr 15, 2020

When you’ve done your screenshot and to estimate the frame and height, did you enable the slow animation mode ? If so, the duration will not match as it’s slowed

Yes I tried running in slow mode, the problem is that the duration is still reported as 250ms in slow mode so I couldn't match my animation with that one automatically.

I would really like to know the slow down factor as it would help me debugging the delay issue. If I multiply the duration by 20x, the duration seem to match perfectly when running in slow mode without me adding the extra duration. If I multiply by 12x and also add 12x my extra duration, everything also matches up.

When running in normal mode, both in simulator and on device, I need the to add the extra duration in order for the animations to match 😕

Sorry for the delay, I'm little bit busy this week, I'll try to take a look as soon as I can, let me know if you figure it out ! 👍

@LinusU
Copy link
Member

LinusU commented Apr 16, 2020

No worries, I've had a very busy week as well, might get some more time this weekend ☺️

@fukemy
Copy link

fukemy commented Jul 25, 2022

i didnt see any update, plz help @magrinj @LinusU

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants