summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Rex <julian.rex@mapbox.com>2018-05-11 11:48:35 -0400
committerJulian Rex <julian.rex@mapbox.com>2018-05-17 17:29:47 -0400
commit01e2f78ccba221290b0e4ae89180477b552dd9b8 (patch)
tree5a7162e33cb88ed0d99efc64705d63eff551238d
parent1aa5c67837a19d5f8ba8f7336f183da83e68441c (diff)
downloadqtlocation-mapboxgl-upstream/jrex-11875-point-in-callout.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-xplatform/ios/vendor/SMCalloutView/SMCalloutView.m44
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