fix: Math.floor animatedIndex value in BottomSheetBackdrop to fix And…
Motivation
On some Android devices, with disabled animations, any screen with the <GorhomBottomSheet/> component appears to "freeze". No component on the screen is able to be interacted with. The user cannot open the bottom sheet, click any buttons, or even scroll.
Steps to reproduce
- Use an Android device (I use a Pixel 9, Android 16 simulator)
- Go into the device settings and disable animations (Settings > Accessibility > Color & motion > toggle Remove animations "on")
- Go to a screen on your device that includes a <GorhomBottomSheet/> component that is rendered "closed" on mount with prop: index={-1} and has a
backdropComponent. - Actual: User will not be able to interact with any component on screen. Expected: User should be able to interact with the app like normal and open the bottom sheet.
Problem
The root of the issue appears to be the useAnimatedReaction hook in the BottomSheetBackdrop.tsx component. The screen appears to "freeze" because although the backdrop is not visible, the backdrop logic is incorrectly disabling the touchability of the screen. On certain Android devices with reduced animations "on", the sharedValue of animatedIndex.value only reaches the value of -0.999… and never crosses the threshold of -1 which is the disappearsOnIndex value. Thus, the return value on line 118 will always equal "false" and cause the handleContainerTouchability function to disable the pointerEvents and appear to "freeze" the screen.
Solution
The proposed solution is to Math.floor() the animatedIndex sharedValue before comparing it to the disappearsOnIndex value. This will ensure that if the sharedValue does not quite reach the disappearsOnIndex value, it will not incorrectly disable touchability. In my app, I have this fixed as a local patch but am looking for a more long-term solution with this PR.
Listed below are previous closed issues related to this fix: https://github.com/gorhom/react-native-bottom-sheet/issues/807 https://github.com/gorhom/react-native-bottom-sheet/issues/1882 https://github.com/gorhom/react-native-bottom-sheet/issues/527 https://github.com/gorhom/react-native-bottom-sheet/issues/566
Confirmed this fixed issues on my Pixel 9a making device unresponsive.
Inspecting the elements showed the BottomSheetBackdrop was covering the entire screen, consuming pointer events.
The issue would occur randomly with animations turned on. Turning animations off however made the issue appear 100% of the time.
Although Math.floor() fixes the blocked pointer events, I noticed it introduced a new behavior where you can tap through the backdrop until the bottom sheet is completely done opening.
~~I am wondering if Math.round() would be a better solution without implementing any complex logic?~~
Both Math.floor() & Math.round() leave too big of a window where the backdrop can still be touched through. If you need the bottom sheet to restrict page interaction, that can be a serious issue.
I do not think this package is inherently doing anything wrong & the bug is at a much lower level since its so device & OS specific.
Even though its a 'magic number' solution, I will probably use this workaround until the root issue is solved.
const EPSILON = 0.001
useAnimatedReaction(
() => animatedIndex.value <= (disappearsOnIndex + EPSILON),
(shouldDisableTouchability, previous) => {
if (shouldDisableTouchability === previous) {
return;
}
runOnJS(handleContainerTouchability)(shouldDisableTouchability);
},
[disappearsOnIndex]
);
thanks @margreen94 for submitting this PR and detailing the issue.
For me based on the information provided, it seems to me that we need to address the issue with no-animation accessibility issue on Android devices to be handled properly. Unfortunately accessibility is not my strong skill to solve this issue. Let me investigate it first, then i'll decide either it worth investing the root cause or accept the short term solution.
Seeing this issue on rn 0.81.4 with new arch but noting this is with reanimated v4 which I realize is not listed as supported by bottom sheet. Several users reported the issue on Android with various OS versions and different devices. Not sure what is the common denominator but I was able to reproduce it with a Pixel 9 sdk 36 emulator.
I did not see this issue on 0.75.5 old arch with reanimated v3.
The PR does solve the issue for me. Thanks!
Hello, is it going to be merged? im facing freezing issue on android device using expo sdk53, reanimated v4
+1 "react-native": "0.81.4", "react-native-reanimated": "^3.19.1",
@gorhom Hello again! Any update on this being merged?
I encountered this issue and it was quite unpleasant. Works on Web and iOS but on Android whole UI becomes unresponsive. But without it - there is no "backdrop" component - so you have to use it - leaving no chance
Thank you for this PR @margreen94!
Did you confirm that your PR fixes this freeze of the UI on androids?
if Yes - then why it is not merged already?