Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react native maps: center marker onPress before Callout is displayed

When a user presses on a marker I am calling animateToCoordinate to center the marker in the middle of the screen. The problem is that the callout is rendered to the position of the region before animateToCoordinate is done its animation so the callout is displayed somewhat offscreen. is there anyway to delay callout display until animateToRegion is finished? Or is there another way to go about this entirely that I am not seeing?

 <MapView
    ref = {(mapView) => { _mapView = mapView; }}
    style={styles.map} 
    region={this.state.mapRegion}
    showsUserLocation = {true}
    showsMyLocationButton   = {true}
    followUserLocation={true}
    onRegionChange={this.onRegionChange.bind(this)}>


 {data.near.map(marker => 
   {if(marker.posts.length != 0){
     return (
      <MapView.Marker
      coordinate={{latitude: marker.location.latitude,
            longitude: marker.location.longitude}}
      title={marker.name}
      description={marker.description}
      onPress={ e => _mapView.animateToCoordinate({
        latitude: e.nativeEvent.coordinate.latitude,
        longitude:  e.nativeEvent.coordinate.longitude
      }, 500)}
      onCalloutPress={ e => this._onPressItem(marker.id)}
    >
    <Icon name="ios-pin" style={{ fontSize: 45, color: '#f04c34'}} />

    <MapView.Callout 
            style={{ flex: -1, position: 'absolute', width: width}}>
    <ListItem >

    <Body >
        <View style={{flex: 1,
        flexDirection: 'row',
        justifyContent: 'space-between',}}>
    <Text style={{fontSize: 18, color: '#38383a', marginBottom: 10, fontWeight: 'bold'}} 
    >{marker.name}</Text>

    <Text style={{fontSize: 14, color: '#38383a', fontWeight: 'bold'}}>{marker.distance.toFixed(2)} miles</Text>
</View>
    <Text style={{fontSize: 16,  fontFamily: 'Avenir', marginBottom: 15}}
    >{marker.infoText}</Text>

    <Text>
    <Text style={{fontSize: 12, color: '#38383a', fontWeight: 'bold'}}
    >{marker.address}</Text>

    </Text>

        </Body>
        <Right></Right>




</ListItem>
  </MapView.Callout>
    </MapView.Marker>
     )
   }else return null;

   })}
  </MapView>
like image 532
john Avatar asked Sep 16 '17 04:09

john


1 Answers

I am having this precise issue as well. My current solution is to make my marker's onPress look something like this:

markerOnPress (coord) {
  TIME_FOR_ANIMATION = 700;
  this.mapview.animateToCoordinate(coord);
  setTimeout(() => {
    this.markerRef.showCallout();
  }, TIME_FOR_ANIMATION);
}

And my marker looks like this:

<Marker
  ref={(ref) => { this.markerRef = ref; }}
  coordinate={coord}
  title={someTitle}
  description={someDescription}
  onPress={() => this.onMarkerPress(coord)}
/>

This works alright, although there is some unwanted behavior still occurring and I'm not sure why. Now when I click on a marker, the callout appears immediately, then disappears before animating to the coordinate, animates to the coordinate, and then displays the callout as desired. I have no idea why it's still immediately displaying the callout initially. I tried fixing this by making the first line of markerOnPress this.markerRef.hideCallout() but this had no noticeable effect.

like image 121
jaxondk Avatar answered Oct 16 '22 07:10

jaxondk