react-native-maps: onPress function not being called as child of Callout

Is this a bug report?

Yes

Have you read the Installation Instructions?

Yep

Environment

“react”: “^16.5.0”, “react-native”: “^0.57.1”, “react-native-maps”: “^0.19.0”,

simulator: iPhone 7 - 12.0

Steps to Reproduce

Add a child with an onPress callback inside a MapView.Callout component

Expected Behavior

The onPress callback should be called

Actual Behavior

It does not get called

Reproducible Demo

image

<MapView.Callout>
  <TouchableOpacity onPress={() => { console.log('this does not get called 😞') }}>
    <Text style={{ padding: 10, backgroundColor: 'white' }}>
      Click me!
    </Text>
  </TouchableOpacity>
</MapView.Callout>

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 12
  • Comments: 35 (1 by maintainers)

Most upvoted comments

My very dirty solution:

  1. Made custom callout with fixed dimensions and add onPress to Callout component.
<Marker>
// Your stuff

<Callout tooltip onPress={this.onCalloutPress}>
    <View style={style.callout}>
        <View style={style.action}>
            { getIcon('running', 20, 'rgb(70, 70, 70)') }
         </View>
         <View style={style.action}>
             { getIcon('comment-dots', 20, 'rgb(70, 70, 70)') }
          </View>
      </View>
</Callout>
</Marker>
callout: {
    width: 130,
    flexDirection: 'row',
    justifyContent: 'space-between',
},
action: {
    width: 40,
    height: 40,
},
  1. See and detect point object into nativeEvent and handle taps!
onCalloutPress = e => {
    const { point } = e.nativeEvent;
    const { onPressRun, onPressMessage } = this.props;

    this.marker.hideCallout();

    if (point.x < 65) { // 65 it's center of Callout
        onPressRun();
    } else {
        onPressMessage();
    }
};

😸

This problem is still happening on 2022 😦

Hey guys I solved the problem by wrapping my button with <MapView.CalloutSubview> and having onPress event attached to that. Example:

<MapView.Callout>
  <MapView.CalloutSubview style={{ marginLeft: 'auto', marginRight: 'auto' }} onPress={() => { this.props.navigation.navigate('Tables') }}>
    <Button
        shadowless
        color="orange"
        style={{ alignSelf: 'center' }}
     >
       View Tables
     </Button>
  </MapView.CalloutSubview>
<MapView.Callout>

@nathmack looking again, I think you might want to use this instead of a touchable: https://github.com/react-community/react-native-maps/blob/master/docs/callout.md#events

Hey guys I solved the problem by wrapping my button with <MapView.CalloutSubview> and having onPress event attached to that. Example:

<MapView.Callout>
  <MapView.CalloutSubview style={{ marginLeft: 'auto', marginRight: 'auto' }} onPress={() => { this.props.navigation.navigate('Tables') }}>
    <Button
        shadowless
        color="orange"
        style={{ alignSelf: 'center' }}
     >
       View Tables
     </Button>
  </MapView.CalloutSubview>
<MapView.Callout>

Thanks…Its Working for me.

@ossraju no problem! I’ve found my problem was that I was styling some components with zIndex (just trying things out) and then forgot about it. Once I removed zIndex it started working as intended (on Android, iOs was working fine).

It works for me on iOS with Apple Maps. But on Android, the onPress for the Callout itself seems to take precedence over any elements that you’ve set up with onPress within that Callout. And if I’ve set no onPress on the Callout, then nothing at all happens on Android!

Another issue is that on Android, the Callout’s own onPress event will give a nice visual feedback that it’s been tapped - a bit like a TouchableOpacity - but the iOS version doesn’t. I had to use a bit of platform-specific code to use a TouchableOpacity on iOS, and the Callout’s onPress on Android, so I get nice onPress visual feedback on both.

+1 And when I set provider to null, I have exception: undefined is not an object (evaluating 'this._mapManagerCommand(name).apply')