react-native-safe-area-context icon indicating copy to clipboard operation
react-native-safe-area-context copied to clipboard

SafeAreaView rendering children under unsafe area

Open RodSarhan opened this issue 9 months ago • 14 comments

Description

SafeAreaView from doesn't respect safe areas on iOS when used alongside an animated view with {translateY: 0} in the same screen. Using a basic view and padding it with insets from useSafeAreaInsets seems to work normally.

This was originally reported here: https://github.com/kirillzyusko/react-native-keyboard-controller/issues/809

Steps to reproduce

  1. Mount a screen that has both SafeAreaView and an animated view with translateY = 0
  2. SafeAreaView child renders under "Unsafe" area.

Snack or a link to a repository

https://snack.expo.dev/@rodsar/safeareaview-issue

Safe Area Context version

5.2.0

React Native version

0.76

Platforms

iOS

Architecture

None

Build type

None

Device

iOS simulator

Device model

No response

Acknowledgements

Yes

RodSarhan avatar Mar 04 '25 11:03 RodSarhan

You're not importing SafeAreaView from this library - it's coming from react-native. Was that just a typo in the example, or is this an actual issue?

jacobp100 avatar Mar 04 '25 12:03 jacobp100

Sorry for that, yeah it was a typo, i edited the example and got the same behavior

RodSarhan avatar Mar 04 '25 12:03 RodSarhan

What happens if you change the <> fragment into <View style={{ flex:1 }}>?

jacobp100 avatar Mar 04 '25 14:03 jacobp100

Yeah i just tried adding a parent view and got the same result

RodSarhan avatar Mar 04 '25 14:03 RodSarhan

I can see the issue in the expo snack you provided. I suspect there's some dodgy interaction with reanimated that's breaking the layout and stopping the padding being applied to the SafeAreaView. I'm not 100% sure it's this side - as far as I'm aware we're doing everything correctly

I'll leave this issue open in case it is our side - but to set some expectations, I don't think it will get looked at. You're welcome to have an attempt at debugging it, we're good at merging PRs people send us

jacobp100 avatar Mar 04 '25 14:03 jacobp100

I just created issue on Reanimated repository. https://github.com/software-mansion/react-native-reanimated/issues/7220

kdwkr avatar Mar 10 '25 15:03 kdwkr

We have noticed something similar happening for our app without using a reanimated View directly. It seems to happen randomly and reinstalling the app fixes it.

We have a nested SafeAreaView where the top edge of the child doesn't get applied. Something like this:

<KeyboardAvoidingView
  behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
  className="flex-1">
  <SafeAreaView edges={['left', 'right', 'bottom']}>
    <SafeAreaView edges={['top']}>...</SafeAreaView> // Top doesn't get applied
    ...
  </SafeAreaView>
</KeyboardAvoidingView>

I'm have been able to replicate it once locally on a simulator (iPhone 15 Pro - iOS 17.2), and by replacing the inner SafeAreaView with paddings from useSafeAreaInsets fixes it.

I'm sorry for being a bit vague but the issue seems to have come out of thin air.

FredrikErikJohansson avatar Mar 12 '25 08:03 FredrikErikJohansson

Try to remove <GestureHandlerRootView

priami93 avatar May 26 '25 06:05 priami93

Same issue here. I had to switch to using useSafeAreaInsets. I'm not using an animated view though. I think this is just a general iOS issue. You can see how I can make changes to the CSS and it starts working, but then reverts right back on reloading the app in thius video.

https://github.com/user-attachments/assets/260e5c31-5687-49bc-aca1-12c22aeeaf42

NorseGaud avatar Jun 21 '25 14:06 NorseGaud

Same issue here. I had to switch to using useSafeAreaInsets. I'm not using an animated view though. I think this is just a general iOS issue. You can see how I can make changes to the CSS and it starts working, but then reverts right back on reloading the app in thius video.

issuewithSafeAreaView.mov

Same issue. React native version: 0.81.4 react-native-safe-area-context: 5.6.1

hashhirr avatar Oct 01 '25 12:10 hashhirr

As far as I can tell, there is some kind of bug on iOS+Fabric where <SafeAreaView> intermittently fails to set up its safe area insets correctly during initialization, leaving them set to zero for the lifetime of the component. After reproducing this (by setting up my app to delete and recreate a view repeatedly and observing that the behavior is inconsistent), I poked around and managed to make the problem disappear with the following patch:

diff --git a/ios/Fabric/RNCSafeAreaViewComponentView.mm b/ios/Fabric/RNCSafeAreaViewComponentView.mm
index 827fa4d..c0b091c 100644
--- a/ios/Fabric/RNCSafeAreaViewComponentView.mm
+++ b/ios/Fabric/RNCSafeAreaViewComponentView.mm
@@ -93,6 +93,9 @@ using namespace facebook::react;
 
 - (void)updateStateIfNecessary
 {
+  if (_providerView == nil) {
+    _providerView = [self findNearestProvider];
+  }
   if (_providerView == nil) {
     return;
   }
@@ -149,6 +152,7 @@ using namespace facebook::react;
 - (void)updateState:(State::Shared const &)state oldState:(State::Shared const &)oldState
 {
   _state = std::static_pointer_cast<RNCSafeAreaViewShadowNode::ConcreteState const>(state);
+  [self updateStateIfNecessary];
 }
 
 - (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask

However, I think this is very much addressing a symptom rather than the cause, and I’m pretty sure this change just causes other bugs (in particular, since the behavior is that _providerView isn’t being updated, it might get out of sync in more subtle ways)—it seems like something about the lifecycle management in this component view needs to be adjusted, but this is where I ran out of diagostic abilities and I don’t understand react-native internals nearly well enough to have a suggestion.

@jacobp100 it seems like you have some context here—based on the above information can you point me in the right direction for a good fix?

wolf-at-mystro avatar Oct 03 '25 22:10 wolf-at-mystro

actually, I think this bug report might be two unrelated issues: it sounds like @RodSarhan and @kdwkr’s problem with animated views is consistent, whereas everyone else’s problems with non-animated views is intermittent?

wolf-at-mystro avatar Oct 03 '25 22:10 wolf-at-mystro

I'm experiencing something similar on 5.6.1 and react-native 0.82.0. I have two Modals (react-native Modal object) with SafeAreaView. On one, i had changed to this lib SafeAreaView instead of the react-native one as i saw the notice of deprecation, on the other i had not at first. The one with this lib would have the same issue as @NorseGaud if started first whereas the old way one had no issue. If i open the modal with the old way first then no bug in the new way one. If i restart the app and go on new way first, the bug happen again.

If i use old way for both, they both have no issue. If i use new way for both, they both have the issue. I have a SafeAreaView with the new way for the main part of the app that seems to work as intended.

BenBarr avatar Oct 13 '25 14:10 BenBarr

Same thing here — adding Animated.View to the screen breaks SafeAreaView. The interesting thing though — I'm using two separate SafeAreaViews, and the one that actually contains the animated view inside of it is working fine, but the other one, that have nothing to do with it, breaks.

kuzkokov avatar Oct 15 '25 16:10 kuzkokov