Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prioritize pressing markers based on pins displayed on map #5243

Open
skibos opened this issue Dec 2, 2024 · 0 comments
Open

Prioritize pressing markers based on pins displayed on map #5243

skibos opened this issue Dec 2, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@skibos
Copy link

skibos commented Dec 2, 2024

Summary

Hi.

There is problem with priority of press action on custom markers. When marker overlaps another marker then not always this which is on top is handled by onPress prop.

Hi,

I'm experiencing an issue with the priority of the onPress action for custom markers. When one marker overlaps another, the marker on top doesn't always handle the onPress action as expected.

In the latest version (1.20.1), the behavior is shown in this video:
https://github.com/user-attachments/assets/8a94ede4-c09f-4445-8c4a-78e65798a2f7

When I press a marker that is visually on top and then redraw it, it remains on top visibly, but the pressable area sometimes prioritizes the marker below it.

Previously, in version 1.14, the behavior was different:

obraz

Red area: The clickable area for the marker behind.
Green area: The clickable area for the marker in front.

This older behavior was incorrect, as some areas of the front marker weren’t responsive. The current behavior is an improvement, but it’s still not perfect.

The issue occurs when clicking on the upper part of the top marker—it sometimes triggers the marker below, even though it shouldn’t.

Reproducible sample code

<MapView
        ref={this.map}
        style={style.mapContainer}
        showsUserLocation
        customMapStyle={mapStyle}
        provider="google"
        moveOnMarkerPress={false}
        showsMyLocationButton={false}
        clusterColor={COLOR_PRIMARY}
        zoomEnabled={isMapReady}
        minPoints={MIN_CLUSTERING_POINT}
        radius={60}
        maxZoom={19}
        clusteringEnabled={true}
        animationEnabled={false}
        showsCompass={false}
        initialRegion={{
          latitude: this.getInitialLatitude(),
          longitude: this.getInitialLongitude(),
          latitudeDelta: this.getInitialLatitudeDelta(),
          longitudeDelta: this.getInitialLongitudeDelta(),
        }}
        onRegionChangeComplete={this.onRegionChangeComplete}
        onMapLoaded={this.onMapLoaded}
      >
        {data.map(renderItem)}
      </MapView>


    const renderItem = (item: ServiceProviderMarker) => {
      const isImageLoaded = Boolean(this.state.imageLoaded[item.id]);
      const tracksViewChanges = item.avatar ? !isImageLoaded : false;
      const isMarkerSelected = this.state.id === item.id;

      const tintColor = isMarkerSelected ? COLOR_PRIMARY : COLOR_WHITE;
      const strokeColor = isMarkerSelected ? COLOR_PRIMARY : COLOR_MEDIUM_GREY;
      const serviceIconTintColor = isMarkerSelected ? COLOR_WHITE : COLOR_PRIMARY;
      const accessibilityKey = `${MapAccessibility.Marker}-${item.latitude}-${item.longitude}`;

      const handleMarkerPress = () => {
        onMarkerPress(item);
        this.changeRegion(item.latitude, item.longitude);
        this.markerRef.current?.redraw();
      };

      const handleLoadEnd = () => this.handleOnLoadEnd(item.id);

      const handleLoadStart = () => this.handleOnLoadStart(item.id);

      return (
        <Marker
          ref={this.markerRef}
          onPress={handleMarkerPress}
          coordinate={{ latitude: item.latitude, longitude: item.longitude }}
          tracksViewChanges={tracksViewChanges}
          key={`MapMarker-${item.id}-${item.latitude}-${item.longitude}-markerSelected: ${isMarkerSelected.toString()}`}
          title={accessibilityKey}
          style={[style.markerContainer, isMarkerSelected && style.markerSelected]}
        >
          <View style={[style.markerBody, isMarkerSelected && style.scaledMarker]}>
            <View>
              <View style={style.markerIcon}>
                <MarkerIcon color={tintColor} stroke={strokeColor} />
              </View>
              <View style={style.markerAvatarRounding}>
                {item.avatar ? (
                  <Image
                    onLoadEnd={handleLoadEnd}
                    onLoadStart={handleLoadStart}
                    style={style.markerAvatar}
                    source={{ uri: item.avatar.includes('://') ? item.avatar : getFileUrl(config.SUFFIX, item.avatar || '') || '' }}
                  />
                ) : (
                  <Avatar width={AVATAR_SIZE} height={AVATAR_SIZE} />
                )}
              </View>
            </View>
          </View>
        </Marker>
      );
    };

Steps to reproduce

Render markers on map (OS doesnt matter), press specific part of marker

Expected result

Marker visible on top should be always pressed.

Actual result

Marker visible on top is not always pressed (sometimes is pressed marker below of top marker)

React Native Maps Version

1.20.1

What platforms are you seeing the problem on?

Android, iOS (Google Maps)

React Native Version

"0.74.6

What version of Expo are you using?

SDK 51

Device(s)

iPhone 15, Pixel 6

Additional information

No response

@skibos skibos added the bug Something isn't working label Dec 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant