react-native-maps: [IOS] onRegionChangeComplete is not firing up at all

Bug report

Summary

onRegionChangeComplete is not firing up at any point on ios.

Environment info

  react-native: 0.66.4
  react: 17.0.2
  react-native-maps: ^0.30.1

Target Platform: iOS - 14.5 Simulator/iPhone 12,

MapProvider: AppleMaps

react-native info output:

System: OS: macOS 11.2.3 CPU: (4) x64 Intel® Core™ i5-5257U CPU @ 2.70GHz Memory: 271.91 MB / 8.00 GB Shell: 5.8 - /bin/zsh Binaries: Node: 16.14.0 - /usr/local/bin/node Yarn: 1.22.17 - ~/.yarn/bin/yarn npm: 8.3.1 - /usr/local/bin/npm Watchman: 4.9.0 - /usr/local/bin/watchman Managers: CocoaPods: 1.10.2 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: iOS 14.5, DriverKit 20.4, macOS 11.3, tvOS 14.5, watchOS 7.4 Android SDK: API Levels: 23, 24, 25, 26, 28, 29, 30 Build Tools: 23.0.1, 26.0.1, 28.0.3, 29.0.2, 29.0.3, 30.0.2 System Images: android-28 | Intel x86 Atom_64 Android NDK: Not Found IDEs: Android Studio: 4.1 AI-201.8743.12.41.6953283 Xcode: 12.5.1/12E507 - /usr/bin/xcodebuild Languages: Java: 1.8.0_252 - /usr/bin/javac npmPackages: @react-native-community/cli: Not Found react: 17.0.2 => 17.0.2 react-native: 0.66.4 => 0.66.4 react-native-macos: Not Found npmGlobalPackages: react-native: Not Found

Steps to reproduce

  1. Set up new react native project
  2. Install react-native-maps
  3. Follow all instructions given in installation.md file
  4. Try to fire onRegionChangeComplete on ios

Describe what you expected to happen:

  1. When scroll on map ends then onRegionChangeComplete should fire

Describe what you actually happens:

  1. After I stop scrolling map onRegionChangeComplete is not firing as it’s getting fired on android.

Reproducible sample code

<View style={styles.mapContainer}>
          <MapView
            ref={mapRef}
            style={styles.map}
            showsUserLocation
            showsMyLocationButton={false}
            zoomEnabled
            onRegionChangeComplete={onRegionChange}
            initialRegion={initialRegion}
          />

          <View style={styles.markerFixed}>
            <Image
              resizeMode="contain"
              style={{
                width: 40,
                height: 40,
              }}
              source={require('../../assets/images/map-marker.png')}
            />
          </View>
        </View>

const styles = StyleSheet.create ({
  mapContainer: {
    height: 400,
    width: 400,
    justifyContent: 'flex-end',
    alignItems: 'center',
  },
  map: {
    ...StyleSheet.absoluteFillObject,
  },
  markerFixed: {
    left: '50%',
    marginLeft: -24,
    marginTop: -48,
    position: 'absolute',
    top: '50%',
  },
}));

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 23

Commits related to this issue

Most upvoted comments

If you like I’ll open a pull request with the fix.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

The issue is due to AirMapManager animate camera method

`   // don't emit region change events when we are setting the camera
        BOOL originalIgnore = mapView.ignoreRegionChanges;
        mapView.ignoreRegionChanges = YES;
        [AIRMap animateWithDuration:duration/1000 animations:^{
            [mapView setCamera:camera animated:YES];
        } completion:^(BOOL finished){
            mapView.ignoreRegionChanges = originalIgnore;
        }];`

If it’s called while a previous animation is still running (i.e. calling repeatedly from a map ref as response of a markers flat list scroll) the originalIgnore value will be read as true and set as true on animation end, preventing forever the map to emit RegionChangeEvent

` if (!mapView.ignoreRegionChanges && mapView.onChange) {
    MKCoordinateRegion region = mapView.region;
    if (!CLLocationCoordinate2DIsValid(region.center)) {
        return;
    }`

I have patched changing the mapView.ignoreRegionChanges type from boolean to int and use it as a counter. Hope this help

I used lodash debounce. But I works only in simulator for some reason it doesn’t work on real device.

@aliwaqar981 can you please reopen the issue? Im glad you found a workaround but this is an actual bug that needs fixing.