问题
I'm using react native maps and I'm trying to add en event listener when a marker callout is pressed. It works on Android but not on IOS. In this first snippet calloutPress gets called on Android but not on IOS:
<MapView
provider={PROVIDER_GOOGLE}
style={styles.map}
rotateEnabled={false}
mapType="standard"
initialRegion={region}
>
<Marker coordinate={markerCoordinate} onCalloutPress={() => this.calloutPress()}>
<Callout>
<View>
<Text style={styles.calloutTitle}>My title</Text>
<Text style={styles.calloutDescription}>My description</Text>
</View>
</Callout>
</Marker>
</MapView>
I also tried a touchable opacity inside the callout, now calloutPress is not called either on Android or IOS:
<MapView
provider={PROVIDER_GOOGLE}
style={styles.map}
rotateEnabled={false}
mapType="standard"
initialRegion={region}
>
<Marker coordinate={markerCoordinate}>
<Callout>
<TouchableOpacity onPress={() => this.calloutPress()}>
<Text style={styles.calloutTitle}>My title</Text>
<Text style={styles.calloutDescription}>My description</Text>
</TouchableOpacity>
</Callout>
</Marker>
</MapView>
Here's the full class:
import React, { Component } from "react";
import { View, StyleSheet, Text, TouchableOpacity } from "react-native";
import MapView, { Marker, Callout, PROVIDER_GOOGLE } from "react-native-maps";
export default class MapTabs extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View style={styles.mapContainer}>
<MapView
provider={PROVIDER_GOOGLE}
style={styles.map}
rotateEnabled={false}
mapType="standard"
initialRegion={region}
>
<Marker coordinate={markerCoordinate}>
<Callout>
<TouchableOpacity onPress={() => this.calloutPress()}>
<Text style={styles.calloutTitle}>My title</Text>
<Text style={styles.calloutDescription}>My description</Text>
</TouchableOpacity>
</Callout>
</Marker>
</MapView>
</View>
);
}
calloutPress() {
console.log("hello!");
}
}
const region = {
latitude: 54.403664,
longitude: 14.769657,
latitudeDelta: 30,
longitudeDelta: 30
};
const markerCoordinate = { latitude: 54.403664, longitude: 14.769657 };
const styles = StyleSheet.create({
mapContainer: {
width: "100%",
height: "100%",
zIndex: 0
},
map: {
flex: 1
},
calloutTitle: {
fontSize: 17,
marginBottom: 5,
fontWeight: "bold"
},
calloutDescription: {
fontSize: 14
}
});
回答1:
After some additional research I found this open issue https://github.com/react-native-community/react-native-maps/issues/2223
The issue states that using provider={PROVIDER_GOOGLE} and a custom style on MapView is making onCalloutPress not trigger on IOS. It does trigger when using native provider.
Apparently there's an onPress event on the callout and using that makes it work on IOS as well. Here's a final solution working on both android and ios with google provider, it only trigger once on each platform:
import React, { Component } from "react";
import { View, StyleSheet, Text } from "react-native";
import MapView, { Marker, Callout, PROVIDER_GOOGLE } from "react-native-maps";
export default class MapTabs extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View style={styles.mapContainer}>
<MapView
provider={PROVIDER_GOOGLE}
style={styles.map}
rotateEnabled={false}
mapType="standard"
initialRegion={region}
>
<Marker
coordinate={markerCoordinate}
onCalloutPress={() => this.calloutPress()}
>
<Callout onPress={() => this.calloutPress()}>
<View>
<Text style={styles.calloutTitle}>My title</Text>
<Text style={styles.calloutDescription}>My description</Text>
</View>
</Callout>
</Marker>
</MapView>
</View>
);
}
calloutPress() {
console.log("hello!");
}
}
const region = {
latitude: 54.403664,
longitude: 14.769657,
latitudeDelta: 30,
longitudeDelta: 30
};
const markerCoordinate = { latitude: 54.403664, longitude: 14.769657 };
const styles = StyleSheet.create({
mapContainer: {
width: "100%",
height: "100%",
zIndex: 0
},
map: {
flex: 1
},
calloutTitle: {
fontSize: 17,
marginBottom: 5,
fontWeight: "bold"
},
calloutDescription: {
fontSize: 14
}
});
If you don't want to add event listeners that aren't triggered, make the onPress and onCalloutPress platform dependent.
回答2:
You can use MapView.Callout
Could you try this?
export default class MapTabs extends Component {
constructor(props) {
super(props);
}
calloutPress() {
console.log("hello!");
}
render() {
return (
<View style={styles.mapContainer}>
<MapView
provider={PROVIDER_GOOGLE}
style={styles.map}
rotateEnabled={false}
mapType="standard"
initialRegion={region}
>
<MapView.Marker
coordinate={markerCoordinate}
>
<MapView.Callout>
<TouchableOpacity
onPress={() => this.calloutPress()}
>
<Text style={styles.calloutTitle}>My title</Text>
<Text style={styles.calloutDescription}>My description</Text>
</TouchableOpacity>
</MapView.Callout>
</MapView.Marker>
</MapView>
</View>
);
}
}
来源:https://stackoverflow.com/questions/57233394/react-native-maps-callout-press-not-triggering-on-ios