diff options
author | Julian Rex <julian.rex@mapbox.com> | 2018-05-11 11:48:35 -0400 |
---|---|---|
committer | Julian Rex <julian.rex@mapbox.com> | 2018-05-17 17:29:47 -0400 |
commit | 01e2f78ccba221290b0e4ae89180477b552dd9b8 (patch) | |
tree | 5a7162e33cb88ed0d99efc64705d63eff551238d | |
parent | 1aa5c67837a19d5f8ba8f7336f183da83e68441c (diff) | |
download | qtlocation-mapboxgl-01e2f78ccba221290b0e4ae89180477b552dd9b8.tar.gz |
Provide custom hit test for callout views to avoid selecting callout when tapping in blank space. Refs #11875upstream/jrex-11875-point-in-callout
-rwxr-xr-x | platform/ios/vendor/SMCalloutView/SMCalloutView.m | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/platform/ios/vendor/SMCalloutView/SMCalloutView.m b/platform/ios/vendor/SMCalloutView/SMCalloutView.m index a0049a3e2d..81517c2b12 100755 --- a/platform/ios/vendor/SMCalloutView/SMCalloutView.m +++ b/platform/ios/vendor/SMCalloutView/SMCalloutView.m @@ -28,6 +28,8 @@ #define TOP_ANCHOR_MARGIN 13 // all the above measurements assume a bottom anchor! if we're pointing "up" we'll need to add this top margin to everything. #define COMFORTABLE_MARGIN 10 // when we try to reposition content to be visible, we'll consider this margin around your target rect +#define CHECK_CALLOUT_SHAPE_FOR_HIT_TEST + NSTimeInterval const kMGLSMCalloutViewRepositionDelayForUIScrollView = 1.0/3.0; @interface MGLSMCalloutView () @@ -62,6 +64,28 @@ NSTimeInterval const kMGLSMCalloutViewRepositionDelayForUIScrollView = 1.0/3.0; return self; } +#ifdef CHECK_CALLOUT_SHAPE_FOR_HIT_TEST +- (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; +} +#endif + - (BOOL)supportsHighlighting { if (![self.delegate respondsToSelector:@selector(calloutViewClicked:)]) return NO; @@ -738,6 +762,26 @@ static UIImage *blackArrowImage = nil, *whiteArrowImage = nil, *grayArrowImage = return layer; } +#ifdef CHECK_CALLOUT_SHAPE_FOR_HIT_TEST +- (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; +} +#endif + @end @implementation MGLSMCalloutBackgroundView |