Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

[6749] fix annotation tap detection (smaller area for annotation imag… #6756

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions platform/ios/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
* Fixed an issue that could reset user-added transformations on annotation views. ([#6166](https://github.com/mapbox/mapbox-gl-native/pull/6166))
* Fixed an issue that caused an annotation view to disappear if it isn’t created using the annotation view reuse queue. ([#6485](https://github.com/mapbox/mapbox-gl-native/pull/6485))
* Deprecated `-[MGLMapViewDelegate mapView:alphaForShapeAnnotation:]` in favor of specifying an alpha component via `-[MGLMapViewDelegate mapView:strokeColorForShapeAnnotation:]` or `-[MGLMapViewDelegate mapView:fillColorForPolygonAnnotation:]`. ([#6706](https://github.com/mapbox/mapbox-gl-native/pull/6706))
* Fixed annotation tap detection (native touch detection on annotation views). ([#6749](https://github.com/mapbox/mapbox-gl-native/issues/6749))

### Networking and offline maps

Expand Down
57 changes: 26 additions & 31 deletions platform/ios/src/MGLMapView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1423,18 +1423,6 @@ - (void)handleSingleTapGesture:(UITapGestureRecognizer *)singleTap
}
}

// Handle the case of an offset annotation view by converting the tap point to be the geo location
// of the annotation itself that the view represents
for (MGLAnnotationView *view in self.annotationContainerView.annotationViews)
{
if (view.centerOffset.dx != 0 || view.centerOffset.dy != 0) {
if (CGRectContainsPoint(view.frame, tapPoint)) {
CGPoint annotationPoint = [self convertCoordinate:view.annotation.coordinate toPointToView:self];
tapPoint = annotationPoint;
}
}
}

MGLAnnotationTag hitAnnotationTag = [self annotationTagAtPoint:tapPoint persistingResults:YES];
if (hitAnnotationTag != MGLAnnotationTagNotFound)
{
Expand Down Expand Up @@ -3241,21 +3229,20 @@ - (MGLAnnotationTag)annotationTagAtPoint:(CGPoint)point persistingResults:(BOOL)
// distance between its center and the tap is less than the maximum height
// or width of an installed annotation image or annotation view.
CGRect queryRect = CGRectInset({ point, CGSizeZero },
-_unionedAnnotationRepresentationSize.width,
-_unionedAnnotationRepresentationSize.height);
queryRect = CGRectInset(queryRect, -MGLAnnotationImagePaddingForHitTest,
-MGLAnnotationImagePaddingForHitTest);
-_unionedAnnotationRepresentationSize.width / 2.0,
-_unionedAnnotationRepresentationSize.height / 2.0);
queryRect = CGRectInset(queryRect, -MGLAnnotationImagePaddingForHitTest / 2.0,
-MGLAnnotationImagePaddingForHitTest / 2.0);
std::vector<MGLAnnotationTag> nearbyAnnotations = [self annotationTagsInRect:queryRect];

// Assume that the user is fat-fingering an annotation.
CGRect hitRect = CGRectInset({ point, CGSizeZero },
-MGLAnnotationImagePaddingForHitTest,
-MGLAnnotationImagePaddingForHitTest);
if (nearbyAnnotations.size())
{
// Assume that the user is fat-fingering an annotation.
CGRect hitRect = CGRectInset({ point, CGSizeZero },
-MGLAnnotationImagePaddingForHitTest,
-MGLAnnotationImagePaddingForHitTest);

// Filter out any annotation whose image or view is unselectable or for which
// hit testing fails.
// Filter out any annotation view or annotation whose image is unselectable or
// for which hit testing fails.
auto end = std::remove_if(nearbyAnnotations.begin(), nearbyAnnotations.end(),
[&](const MGLAnnotationTag annotationTag)
{
Expand All @@ -3268,14 +3255,8 @@ - (MGLAnnotationTag)annotationTagAtPoint:(CGPoint)point persistingResults:(BOOL)
MGLAnnotationView *annotationView = annotationContext.annotationView;
if (annotationView)
{
if ( ! annotationView.enabled)
{
return true;
}

CGPoint calloutAnchorPoint = [self convertCoordinate:annotation.coordinate toPointToView:self];
CGRect frame = CGRectInset({ calloutAnchorPoint, CGSizeZero }, -CGRectGetWidth(annotationView.frame) / 2, -CGRectGetHeight(annotationView.frame) / 2);
annotationRect = UIEdgeInsetsInsetRect(frame, annotationView.alignmentRectInsets);
// remove annotation views as they will be tested later
return true;
}
else
{
Expand All @@ -3298,6 +3279,20 @@ - (MGLAnnotationTag)annotationTagAtPoint:(CGPoint)point persistingResults:(BOOL)

nearbyAnnotations.resize(std::distance(nearbyAnnotations.begin(), end));
}

// test annotation views for real touch
for (MGLAnnotationView *annotationView in self.annotationContainerView.annotationViews)
{
if (annotationView.enabled
&& CGRectIntersectsRect(annotationView.frame, hitRect))
{
MGLAnnotationTag tag = [self annotationTagForAnnotation:annotationView.annotation];
if (tag != MGLAnnotationTagNotFound)
{
nearbyAnnotations.push_back(tag);
}
}
}

MGLAnnotationTag hitAnnotationTag = MGLAnnotationTagNotFound;
if (nearbyAnnotations.size())
Expand Down