17

I need to place a <View> with position: 'absolute' so it can overlay another view below. I want this not to be behind the status bar in iOS, so I've put everything inside a <SafeAreaView>.

Unfortunately, the absolute position seems to be relative to the full screen instead of its parent view (the SafeAreaView).

Is there a trick?

const styles = StyleSheet.create({
    safeAreaView: {
      flex: 1,
    },
    map: {
      flex: 1,
    },
    userLocationButton: {
      position: 'absolute',
      right: 12,
      top: 12,
    },
  });

  return (
    <SafeAreaView style={styles.safeAreaView}>
        <ClusteredMapView style={styles.map} />
      )}
        <TouchableOpacity style={styles.userLocationButton}>
          <Image source={UserLocationButton} />
        </TouchableOpacity>
      )}
    </SafeAreaView>
  );

enter image description here

jdanthinne
  • 337
  • 1
  • 2
  • 9

3 Answers3

32

I had the same issue, fixed it by wrapping the absolute element with another View.

<SafeAreaView style={{flex: 1}}>
    <View style={{flex: 1}}>
        <TouchableOpacity style={{height: 40, width: 40, borderRadius: 20}} />
    </View>
</SafeAreaView>
Nicolai Lissau
  • 7,298
  • 5
  • 43
  • 57
  • And just remember (I'm new to RN so I wasn't aware of that) to add `pointerEvents="box-none"` to the `View`, so the map below gets touch events as well. – jdanthinne Feb 03 '20 at 08:16
  • 2
    How does this work? I tried it but unfortunately didn't work for me... – Ken May 03 '21 at 05:32
3

What helped in my case was adding overflow: hidden style to View element above the one with absolute position.

<SafeAreaView style={{ flex: 1 }}>
    <View style={{ overflow: 'hidden' }}>
        <View style={{ position: 'absolute' }}></View>
    </View>
</SafeAreaView>
404.html
  • 136
  • 5
1

add status bar size value to top of absolute styling

get status bar size from this function getStatusBarHeight()

import { Dimensions, Platform, StatusBar } from 'react-native';
function isIphoneX() {
  const dimen = Dimensions.get('window');
  return (
    Platform.OS === 'ios' &&
    !Platform.isPad &&
    !Platform.isTVOS &&
    (dimen.height === 812 ||
      dimen.width === 812 ||
      (dimen.height === 896 || dimen.width === 896))
  );
}
export function getStatusBarHeight(skipAndroid) {
    return Platform.select({
        ios: isIPhoneX() ? 44 : 20,
        android: skipAndroid ? 0 : StatusBar.currentHeight,
        default: 0
    })
}
Aurangzaib Rana
  • 4,028
  • 1
  • 14
  • 23
  • Unfortunately, this solution only work in portrait, but when in landscape, status bar height should be 0. I know I can also observe orientation, but I was wondering if there was an automatic way to handle that… – jdanthinne Jan 24 '20 at 14:54
  • It work, but I hope other solution that can set the button inside the SafeAreaView even use absolute – tuanngocptn Oct 14 '20 at 10:24