diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm index 8e1edb96067e876d57d640f5a54aad714fb5c4cc..6ca2f334dd4882ad69912b3185ed996b0a26fadd 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm @@ -29,8 +29,6 @@ void FlutterPlatformViewsController::OnMethodCall(FlutterMethodCall* call, Flutt OnDispose(call, result); } else if ([[call method] isEqualToString:@"acceptGesture"]) { OnAcceptGesture(call, result); - } else if ([[call method] isEqualToString:@"rejectGesture"]) { - OnRejectGesture(call, result); } else { result(FlutterMethodNotImplemented); } @@ -127,24 +125,6 @@ void FlutterPlatformViewsController::OnAcceptGesture(FlutterMethodCall* call, result(nil); } -void FlutterPlatformViewsController::OnRejectGesture(FlutterMethodCall* call, - FlutterResult& result) { - NSDictionary* args = [call arguments]; - int64_t viewId = [args[@"id"] longLongValue]; - - if (views_.count(viewId) == 0) { - result([FlutterError errorWithCode:@"unknown_view" - message:@"trying to set gesture state for an unknown view" - details:[NSString stringWithFormat:@"view id: '%lld'", viewId]]); - return; - } - - FlutterTouchInterceptingView* view = touch_interceptors_[viewId].get(); - [view blockGesture]; - - result(nil); -} - void FlutterPlatformViewsController::RegisterViewFactory( NSObject* factory, NSString* factoryId) { @@ -289,9 +269,6 @@ void FlutterPlatformViewsController::EnsureGLOverlayInitialized( // invoking an acceptGesture method on the platform_views channel). And this is how we allow the // Flutter framework to delay or prevent the embedded view from getting a touch sequence. @interface DelayingGestureRecognizer : UIGestureRecognizer -- (instancetype)initWithTarget:(id)target - action:(SEL)action - forwardingRecognizer:(UIGestureRecognizer*)forwardingRecognizer; @end // While the DelayingGestureRecognizer is preventing touches from hitting the responder chain @@ -324,10 +301,7 @@ void FlutterPlatformViewsController::EnsureGLOverlayInitialized( [[[ForwardingGestureRecognizer alloc] initWithTarget:self flutterView:flutterView] autorelease]; - _delayingRecognizer.reset([[DelayingGestureRecognizer alloc] - initWithTarget:self - action:nil - forwardingRecognizer:forwardingRecognizer]); + _delayingRecognizer.reset([[DelayingGestureRecognizer alloc] initWithTarget:self action:nil]); [self addGestureRecognizer:_delayingRecognizer.get()]; [self addGestureRecognizer:forwardingRecognizer]; @@ -338,34 +312,21 @@ void FlutterPlatformViewsController::EnsureGLOverlayInitialized( - (void)releaseGesture { _delayingRecognizer.get().state = UIGestureRecognizerStateFailed; } - -- (void)blockGesture { - _delayingRecognizer.get().state = UIGestureRecognizerStateEnded; -} - @end -@implementation DelayingGestureRecognizer { - fml::scoped_nsobject _forwardingRecognizer; -} - -- (instancetype)initWithTarget:(id)target - action:(SEL)action - forwardingRecognizer:(UIGestureRecognizer*)forwardingRecognizer { +@implementation DelayingGestureRecognizer +- (instancetype)initWithTarget:(id)target action:(SEL)action { self = [super initWithTarget:target action:action]; if (self) { self.delaysTouchesBegan = YES; self.delegate = self; - _forwardingRecognizer.reset(forwardingRecognizer); } return self; } - (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer { - // The forwarding gesture recognizer should always get all touch events, so it should not be - // required to fail by any other gesture recognizer. - return otherGestureRecognizer != _forwardingRecognizer.get() && otherGestureRecognizer != self; + return otherGestureRecognizer != self; } - (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer @@ -373,12 +334,21 @@ void FlutterPlatformViewsController::EnsureGLOverlayInitialized( return otherGestureRecognizer == self; } -- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { - self.state = UIGestureRecognizerStateBegan; +- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { + // The gesture has ended, and the delaying gesture recognizer was not failed, we recognize + // the gesture to prevent the touches from being dispatched to the embedded view. + // + // This doesn't work well with gestures that are recognized by the Flutter framework after + // all pointers are up. + // + // TODO(amirh): explore if we can instead set this to recognized when the next touch sequence + // begins, or we can use a framework signal for restarting the recognizers (e.g when the + // gesture arena is resolved). + self.state = UIGestureRecognizerStateRecognized; } - (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event { - self.state = UIGestureRecognizerStateCancelled; + self.state = UIGestureRecognizerStateRecognized; } @end @@ -410,12 +380,12 @@ void FlutterPlatformViewsController::EnsureGLOverlayInitialized( - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { [_flutterView touchesEnded:touches withEvent:event]; - self.state = UIGestureRecognizerStateEnded; + self.state = UIGestureRecognizerStateRecognized; } - (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event { [_flutterView touchesCancelled:touches withEvent:event]; - self.state = UIGestureRecognizerStateCancelled; + self.state = UIGestureRecognizerStateRecognized; } - (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h index 7c980896bfceff3d01a86c36b51ce21ec4dcdcfc..4173a1ebf687168e6d972d70167fb16dad0096f7 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h @@ -22,9 +22,6 @@ // Stop delaying any active touch sequence (and let it arrive the embedded view). - (void)releaseGesture; - -// Prevent the touch sequence from ever arriving to the embedded view. -- (void)blockGesture; @end namespace shell { @@ -92,7 +89,6 @@ class FlutterPlatformViewsController { void OnCreate(FlutterMethodCall* call, FlutterResult& result); void OnDispose(FlutterMethodCall* call, FlutterResult& result); void OnAcceptGesture(FlutterMethodCall* call, FlutterResult& result); - void OnRejectGesture(FlutterMethodCall* call, FlutterResult& result); void EnsureOverlayInitialized(int64_t overlay_id); void EnsureGLOverlayInitialized(int64_t overlay_id,