Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Only setting the initial region on a react-native MapView

Use case: Annotations are displayed on a map, using the react-native MapView component. The initial map region is set so that all of the annotations are visible. Annotations are moving around, which triggers re-renders. In addition, the user should be able to pan/zoom around the map, so onRegionChange() and onRegionChangeComplete() attempt to capture region changes and set those in the state; in this way, the map region doesn't reset to the initial map region whenever a re-render occurs.

render: function() {
  ...
  return (
    <MapView
      region={this.state.region}
      annotations={annotations}
      onRegionChange={this.onRegionChange}
      onRegionChangeComplete={this.onRegionChangeComplete}
    />
  );
},

onRegionChange: function(region) {
  this.setState({ region });
},

onRegionChangeComplete: function(region) {
  this.setState({ region });
},

Problem: Setting the updated region in the state doesn't allow for a smooth panning/scrolling experience on the map, due to the delay in updating the state. After a couple of pans or zooms, the map freezes, presumably because it is using the current region saved in the state, and not a more updated region. Wait 1-2 seconds, and the map can be panned/zoomed again, presumably because the region has now been updated in the state.

Question: Is there a way to set the MapView's initial region only, such that a re-render doesn't cause the region to reset? That way, onRegionChange() and onRegionChangeComplete() can be used as delegate methods to perform work on the new region (analogous to MKMapViewDelegate's mapView:regionWillChangeAnimated:), rather than saving the region itself for the purposes of map rendering.

like image 433
Jed Lau Avatar asked Sep 25 '22 14:09

Jed Lau


1 Answers

region is an attribute for demos only, don't use and do not need to use it for real life... try this method in real life(example)

take mine relocate button of animate back to users current location for eg:

<MapView initialRegion = {...some init region} onRegionChangeComplete = {region=>this.setState({region} ref={ref=>this.map=ref}>
</MapView>

<TouchableOpacity onpress={this.onRelocate}><Text>back to my position</Text></TouchableOpacity>

onRelocate = () => {
navigator.geolocation.getCurrentPosition(
      position => {
        Toast.loading("定位中...", 2);
        let region = {
          latitude: position.coords.latitude,
          longitude: position.coords.longitude
        };
        this.map.animateToRegion(region)
}
like image 136
Feng Mu Avatar answered Sep 28 '22 23:09

Feng Mu