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

Commit

Permalink
[ios] Provide custom hit test for callout views (#11939)
Browse files Browse the repository at this point in the history
  • Loading branch information
julianrex authored May 24, 2018
1 parent 5e65cb7 commit 0212fd3
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
1 change: 1 addition & 0 deletions platform/ios/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
* Adjusted when and how the camera transition update and finish callbacks are called, fixing recursion bugs. ([#11614](https://github.com/mapbox/mapbox-gl-native/pull/11614))
* Improved application launch performance.
* Fixed an issue preventing nested key path expressions get parsed accordingly to the spec. ([#11959](https://github.com/mapbox/mapbox-gl-native/pull/11959))
* Added custom `-hitTest:withEvent:` to `MGLSMCalloutView` to avoid registering taps in transparent areas of the standard annotation callout. ([#11939](https://github.com/mapbox/mapbox-gl-native/pull/11939))

## 4.0.1 - May 14, 2018

Expand Down
38 changes: 38 additions & 0 deletions platform/ios/vendor/SMCalloutView/SMCalloutView.m
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,26 @@ - (id)initWithFrame:(CGRect)frame {
return self;
}

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *hitView = [super hitTest:point withEvent:event];

// If we tapped on our container (i.e. the UIButton), then ask the background
// view if the point is "inside". MGLSMCalloutMaskedBackgroundView provides a
// custom implementation that checks against the main callout and the down arrow.
// This avoids taps in "blank" space being detected

if (hitView == self.containerView) {
// Ideally we'd use the background mask to determine whether a tap point
// is valid, but that's overkill in this situation
CGPoint backgroundPoint = [self convertPoint:point toView:self.backgroundView];
if (![self.backgroundView pointInside:backgroundPoint withEvent:event]) {
return nil;
}
}

return hitView;
}

- (BOOL)supportsHighlighting {
if (![self.delegate respondsToSelector:@selector(calloutViewClicked:)])
return NO;
Expand Down Expand Up @@ -738,6 +758,24 @@ - (CALayer *)contentMask {
return layer;
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {

// Only interested in providing a custom pointInside for touches.
if (event.type != UIEventTypeTouches) {
return [super pointInside:point withEvent:event];
}

NSArray *views = @[self.containerView, self.arrowView];
for (UIView *view in views) {
CGPoint viewPoint = [self convertPoint:point toView:view];
if (CGRectContainsPoint(view.bounds, viewPoint)) {
return YES;
}
}

return NO;
}

@end

@implementation MGLSMCalloutBackgroundView
Expand Down

0 comments on commit 0212fd3

Please sign in to comment.