'React Native, TouchableOpacity wrapping floating button get nothing

I'm creating a simple action button (floating button)

This is working :

<View style={{
    width: this.props.size,
    height: this.props.size,
    borderRadius: this.props.size / 2,
    backgroundColor: '#ee6e73',
    position: 'absolute',
    bottom: 10,
    right: 10,
    flexDirection:'row'
}}>
    <Text>
        +
    </Text>
</View>

This is not :

<TouchableOpacity
        onPress={()=>{
        }} >
    <View style={{
        width: this.props.size,
        height: this.props.size,
        borderRadius: this.props.size / 2,
        backgroundColor: '#ee6e73',
        position: 'absolute',
        bottom: 10,
        right: 10,
        flexDirection:'row'
    }}>
        <Text>
            +
        </Text>
    </View>
</TouchableOpacity>

Just wrap with TouchableOpacity then my button not show up without any errors.

React 0.1.7, Android

Then I try move styling from View to TouchableOpacity, It's work

<TouchableOpacity
        onPress={()=>{
        }} 
        style={{
            width: this.props.size,
            height: this.props.size,
            position: 'absolute',
            borderRadius: this.props.size / 2,
            backgroundColor: '#ee6e73',
            bottom: 10,
            right: 10,
        }}>
    <Text>
        +
    </Text>
</TouchableOpacity>

Can any one explain me why?

React Native docs said

[https://facebook.github.io/react-native/docs/touchableopacity.html][1]

A wrapper for making views respond properly to touches. This is done without actually changing the view hierarchy, and in general is easy to add to an app without weird side-effects.

This mean I wrap my original view and it would work as I expected, But it's not.



Solution 1:[1]

From my experience, TouchableOpacity does not work well with absolute positioning. Perhaps if you remove that, the onPress will work again.

Also please note that it is EXTREMELY important what element you render first and what you render last.

For example, if you do:

<View>
    <TouchableOpacity style={{position:'absolute'}} onPress={()=> 
           {console.log("It works or not?")}}>
   </TouchableOpacity>
    <Text style={styles.aStyle}>
        Some text bla bla......
    </Text>
</View>

There is a pretty good chance that the Text will be rendered on top of the TouchableOpacity, therefore you won't be able to get the onPress working.

Then since the position is absolute, all you have to do is render it as the last child of the View:

<View>
    <Text style={styles.aStyle}>
        Some text bla bla
    </Text>
    <TouchableOpacity style={{position:'absolute'}} onPress={()=> 
       {console.log("It works or not?")}}>
   </TouchableOpacity>
</View>

Solution 2:[2]

I know this is old but I had this issue and nothing above worked until adding flex: 1 to my TouchableOpacity.

Solution 3:[3]

TouchableOpacity does not assume the style of the view it is the parent of. You need provide it style information.

Solution 4:[4]

Incase anyone else stumbles across this, and none of these suggestions work my fix was to instead import TouchableOpacity from react-native instead of react-native-gesture-handler

So

import { TouchableOpacity } from "react-native";

Instead of

import { TouchableOpacity } from "react-native-gesture-handler";

Solution 5:[5]

I had a similar issue after a lot of debugging I found out that negative margin was the problem.

Beware of negative margin when using TouchableOpacity

Debugging step:

  1. Remove all the styling
  2. Create fresh component without styling
  3. Make sure it is working without styling
  4. Then state adding your styling

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Thiru
Solution 2 Thingamajig
Solution 3 Hamicorn Fury
Solution 4 Cheyne
Solution 5 Emmanuel Ajaero