2

Scenario: I have a red, green and blue box, each having a yellow box touchable inside. Red and blue boxers are siblings. Green box is a child of red box and is position: absolute so that it is overlapping. Using zIndex on parent of green box (i.e. red box) I managed to overlay green box over both red and blue boxes. Each touchable logs its parent's color when pressed.

[This is Android only Issue]

Issue: Tapping touchable on the green box, in an area where green is overlapping with blue, taps the blue box rather than green box despite green being on top.

Expected Behavior: Green box should be tapped since it is on top.

Screenshot: https://i.ibb.co/PgBsHmn/android-issue-with-position-absolute.png

Snack: https://snack.expo.io/@bgcodes/absolute-position-issue-on-android

Code:

import { View, TouchableOpacity, StyleSheet, Text } from 'react-native'; const App = () => { return ( <View style={styles.container}> <View style={styles.red}> <TouchableOpacity onPress={()=>console.log('red')}> <View style={styles.yellow} /> </TouchableOpacity> <View style={styles.green}> <TouchableOpacity onPress={()=>console.log('green')}> <View style={styles.yellow} /> </TouchableOpacity> </View> </View> <View style={styles.blue}> <TouchableOpacity onPress={()=>console.log('blue')}> <View style={styles.yellow} /> </TouchableOpacity> </View> </View> )} export default App; const styles=StyleSheet.create({ container: { justifyContent: 'center', alignItems: 'center', flex: 1, }, yellow: { height: 90, width: 90, backgroundColor: 'yellow', }, red: { justifyContent: 'center', alignItems: 'center', height: 100, width: 100, backgroundColor: 'red', zIndex: 5, }, green: { justifyContent: 'center', alignItems: 'center', height: 100, width: 100, backgroundColor: 'green', position: 'absolute', left: 30, top: 50, }, blue: { justifyContent: 'center', alignItems: 'center', height: 100, width: 100, backgroundColor: 'blue', zIndex: 1, }, }); 

Any Help would be greatly appreciated 🙏

3 Answers 3

2

Ok, turns out as a workaround you can import TouchableOpacity from 'react-native-gesture-handler' and it works fine. But the issue still persists when using TextInput. i.e. If there was a TextInput (instead of Blue box) underneath the overlapping Green box, pressing greenbox would focux on TextInput.

Edit: Workaround for TextInput. You can use pointerEvents prop on TextInput to ignore touch event.

<TextInput pointerEvents={isOverlapped ? 'none' : 'auto'} /> 
Sign up to request clarification or add additional context in comments.

2 Comments

Yeah, I faced the issue that you said with TextInput. Is there any way to solve that ?
Sure mate, I've edited the above answer for the workaround on TextInput. Hope it helps.
0

The rendering is tricky for your feature. Something like that should work (pseudo code)

Right now, your code look like this:

<RedSquareComponent /> <GreenSquare /> <BlueSquare /> 

In order to have the green square above the blue one, just switch the two.

<RedSquareComponent /> <BlueSquare /> <GreenSquare /> 

Here it is on snack:

https://snack.expo.io/@sportelli/absolute-position-issue-on-android

1 Comment

It is essential for me to have the <Greensquare/> be child of <Redsquare/>.
0

I think that should be good:

import React from 'react'; import { View, TouchableOpacity, StyleSheet, Text } from 'react-native'; const App = () => { return ( <View style={styles.container}> <View style={styles.red}> <TouchableOpacity onPress={() => console.log('red')} style={styles.yellow} /> </View> <View style={styles.green}> <TouchableOpacity onPress={() => console.log('green')} style={styles.yellow} /> </View> <View style={styles.blue}> <TouchableOpacity onPress={() => console.log('blue')} style={styles.yellow} /> </View> </View> ); }; export default App; const styles = StyleSheet.create({ container: { justifyContent: 'center', alignItems: 'center', flex: 1, }, yellow: { height: 90, width: 90, backgroundColor: 'yellow', }, red: { justifyContent: 'center', alignItems: 'center', height: 100, width: 100, backgroundColor: 'red', zIndex: 5, }, green: { justifyContent: 'center', alignItems: 'center', height: 100, width: 100, backgroundColor: 'green', position: 'absolute', left: 170, zIndex: 6, }, blue: { justifyContent: 'center', alignItems: 'center', height: 100, width: 100, backgroundColor: 'blue', zIndex: 1, }, }); 

5 Comments

Have you tested on android or iOS? I can reproduce on android.
Sorry I forgot to mention, it is android only problem. Please try it on Android rather than ios or web.
Oh yes, I see. i tried different things right now but with no luck.
I think you have to find a way to put your 3 TouchableOpacity in the same view. Here you have yellow and green in on view et blue in another and I think that's where come from your problem.
It is essential for me to have the <Greensquare/> be child of <Redsquare/>. What I'm trying to achieve is have a child of a view be on top over its sibling view, which it does but only visually.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.