React native maps callout press not triggering on IOS

↘锁芯ラ 提交于 2021-01-29 11:16:02

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!