Ibrahim Ahmed
Ibrahim Ahmed

Reputation: 2345

TouchableOpacity not working inside an absolute positioned View

I have an absolute-positioned View that holds three TouchableOpacity components, and the three fail to respond they are just not working at all. What is going wrong here?

Code

<View style={[styles.highNormalLowDocListHeaderStateContainer, {width: this.windowWidth, height: this.headerSmallHeight, position: 'absolute', left: 0, top: floatedHeaderTitleTop, elevation: 2}]}>
    <TouchableOpacity onPress={() => this.getDocuments('high')} style={[styles.highNormalLowDocListHeaderStateTextContainer, highSelected.borderStyle]}>
        <Text style={[styles.highNormalLowDocListHeaderStateText, highSelected.textStyle]}>HIGH</Text>
    </TouchableOpacity>
    <TouchableOpacity onPress={() => this.getDocuments('normal')} style={[styles.highNormalLowDocListHeaderStateTextContainer, normalSelected.borderStyle]}>
        <Text style={[styles.highNormalLowDocListHeaderStateText, normalSelected.textStyle]}>NORMAL</Text>
    </TouchableOpacity>
    <TouchableOpacity onPress={() => this.getDocuments('low')} style={[styles.highNormalLowDocListHeaderStateTextContainer, lowSelected.borderStyle]}>
        <Text style {[styles.highNormalLowDocListHeaderStateText, lowSelected.textStyle]}>LOW</Text>
    </TouchableOpacity>
</View>

Screenshot

enter image description here

Upvotes: 65

Views: 75497

Answers (17)

Arash Esfandiari
Arash Esfandiari

Reputation: 1

Adding z-index: 50 to the parent component will fix the problem.

Upvotes: 0

Apatoallo
Apatoallo

Reputation: 55

Add one more View or Div over Touchable opacity and give absolute positioning here

<View style={{position: 'absolute'}}>
  <TouchableOpacity></TouchableOpacity>
 </View>

because when you make the View 'absolute' inside the TouchableOpacity element TouchableOpacity doesnt move with elements inside

 <TouchableOpacity>
    <View style={{position: 'absolute'}}></View>
 </TouchableOpacity>

If you do like this above Touchable opacity doesnt move together with absolute element

Upvotes: 1

sahba
sahba

Reputation: 39

you can use TouchableHighlight instead:

import {  TouchableHighlight } from "react-native";

and change the press color with underlayColor={'lightgray'}

Upvotes: 0

Walter Shub
Walter Shub

Reputation: 662

Often when do absolute positioning you have to put a zIndex because the absolute positioned ui view is sometimes being rendered behind another view

Upvotes: 5

Adam Lee
Adam Lee

Reputation: 66

For me the fix was simple but I don't understand why?

<TouchableOpacity onPress={() => console.log('PRESSED')}>
   <View style={styles.fab}>
     <View style={styles.cartContainer}>
       <Text>{this.state.cartCount}</Text>
     </View>
     <Image source={CART} resizeMode="contain" />
   </View>
 </TouchableOpacity>

To

<TouchableOpacity style={styles.fab} onPress={() => console.log('PRESSED')}>
  <View style={styles.cartContainer}>
    <Text>{this.state.cartCount}</Text>
  </View>
  <Image source={CART} resizeMode="contain" />
</TouchableOpacity>

Styles

fab: {
    position: 'absolute',
    bottom: 40,
    right: 20,
    height: 60,
    width: 60,
}

Hope this helps anyone.

Upvotes: 0

Muhammad Arsalan
Muhammad Arsalan

Reputation: 41

by importing TouchableOpacity from "react-native-gesture-handler" worked for me instead of giving the container View z-index

import { TouchableOpacity} from 'react-native-gesture-handler'

Upvotes: 1

Alexander Obidiegwu
Alexander Obidiegwu

Reputation: 644

None of this answers here worked for me. I had to use import { TapGestureHandler } from 'react-native-gesture-handler'; and wrap the children elements with <TapGestureHandler onBegan={yourFunc} ></TapGestureHandler >

The benefit of this is that it doesn't affect your styles and also accomplishes the same click effect you want. Generally I prefer this.

Upvotes: 0

Sultan Singh Atwal
Sultan Singh Atwal

Reputation: 820

I tried all the other answers but could not get it to work. In my case I had a parent container that had the following styles:

.parentContainer {
    height: '100%',
    width: '100%',
    position: 'absolute',
    top: '-20%'
}

I realized that the children were overflowing out of the parent container and although it was not a big problem in terms of style, all the TouchableOpacity components that overflowed out of the parent container did not work (onPress event did not fire). Basically any TouchableOpacity component that ended up in the bottom 20% of the screen did not work because the parent had been moved up 20% (top: '-20%'). All I had to do was was change the height from 100% to 120% for the parent container and it started working as expected.

Upvotes: 1

Jemzzzz
Jemzzzz

Reputation: 159

What worked for me are:

  • Making sure I use
    import { TouchableOpacity } from 'react-native';
    
  • Removing flex: 1 and just having this style for my parent container:
    { width: '100%', height: '100%'}
    

Upvotes: 2

Tayyab Mazhar
Tayyab Mazhar

Reputation: 1702

In my case the touchable items were inside a FlatList. Using FlatList from 'react-native-gesture-handler' solved this issue for me.

Upvotes: 2

Apurva Aggarwal
Apurva Aggarwal

Reputation: 297

If onPress of TouchableOpacity is not working, In that case, TouchableNativeFeedback will work

Example:

{ Platform.OS === 'ios' ?
  <TouchableOpacity onPress={() => this.showPassordText()}>
    <Text style={{ color: 'red' }}>SHOW</Text>  
  </TouchableOpacity>
  :
  <TouchableNativeFeedback onPress={() => this.showPassordText()}>
    <Text style={{ color: 'red' }}>SHOW</Text>
  </TouchableNativeFeedback>
}

Upvotes: 7

Rishav Kumar
Rishav Kumar

Reputation: 5460

Just add zIndex : 1 to the view containing the buttons.

Also note: adding elevation adds shadow to android button and sometimes elevation may also be a issue if it's added to parent and not added to child then the child button may not work (Rare Case).

eg:

buttonContainers:
  {
    zIndex: 1,
    alignSelf: 'flex-end',
    position: 'absolute',
    top:5,
    right: 5,
    height: 40,
    borderWidth: 1,
    justifyContent: 'center',
    alignContent: 'center',
    width: 80
  },

Upvotes: 92

Thiago Leite
Thiago Leite

Reputation: 925

Look at your import. If import { TouchableOpacity } from 'react-native-gesture-handler'; doesn't work, you need import this from 'react-native'.

Upvotes: 88

AndrewReactDev97
AndrewReactDev97

Reputation: 31

I fixed this issue by adding in a flex: 1 to each parent, and a height/ width to each. also try pulling out each TouchableOpacity into separate view with flex:1 and adding absolute positioning to the child (text) element. I had an animation on my button so it may be a bit different.

Upvotes: 3

Nouar
Nouar

Reputation: 3247

Importing TouchableOpacity from "react-native-gesture-handler" worked for me

import { TouchableOpacity} from 'react-native-gesture-handler'

Upvotes: 61

Serdar D.
Serdar D.

Reputation: 3391

Your absolute element is probably placed in a relative element. If you want to click it, you should remove parent relative rule.

Upvotes: 1

mienaikoe
mienaikoe

Reputation: 510

Even though the tab bar visually appears to be above the content in the list, the touch events for the list may be receiving it before the tab bar. Add a zIndex to the tab bar to allow it to receive touch events first.

Upvotes: 17

Related Questions