未验证 提交 0bc6dc97 编写于 作者: C Chris Yang 提交者: GitHub

Platform_views gesture: let flutter view controller be the media to pass the touches. (#8685)

This PR updated the forwarding gesture recognizer to pass the touch events directly to the FlutterViewContoller instead of FlutterView which ensures the touches events are passed to the framework.
上级 710e9edd
......@@ -22,6 +22,11 @@ void FlutterPlatformViewsController::SetFlutterView(UIView* flutter_view) {
flutter_view_.reset([flutter_view retain]);
}
void FlutterPlatformViewsController::SetFlutterViewController(
UIViewController* flutter_view_controller) {
flutter_view_controller_.reset([flutter_view_controller retain]);
}
void FlutterPlatformViewsController::OnMethodCall(FlutterMethodCall* call, FlutterResult& result) {
if ([[call method] isEqualToString:@"create"]) {
OnCreate(call, result);
......@@ -80,9 +85,9 @@ void FlutterPlatformViewsController::OnCreate(FlutterMethodCall* call, FlutterRe
arguments:params];
views_[viewId] = fml::scoped_nsobject<NSObject<FlutterPlatformView>>([embedded_view retain]);
FlutterTouchInterceptingView* touch_interceptor =
[[[FlutterTouchInterceptingView alloc] initWithEmbeddedView:embedded_view.view
flutterView:flutter_view_] autorelease];
FlutterTouchInterceptingView* touch_interceptor = [[[FlutterTouchInterceptingView alloc]
initWithEmbeddedView:embedded_view.view
flutterViewController:flutter_view_controller_.get()] autorelease];
touch_interceptors_[viewId] =
fml::scoped_nsobject<FlutterTouchInterceptingView>([touch_interceptor retain]);
......@@ -355,13 +360,15 @@ void FlutterPlatformViewsController::EnsureGLOverlayInitialized(
// as well. So during this phase as well the ForwardingGestureRecognizer dispatched the events
// directly to the FlutterView.
@interface ForwardingGestureRecognizer : UIGestureRecognizer <UIGestureRecognizerDelegate>
- (instancetype)initWithTarget:(id)target flutterView:(UIView*)flutterView;
- (instancetype)initWithTarget:(id)target
flutterViewController:(UIViewController*)flutterViewController;
@end
@implementation FlutterTouchInterceptingView {
fml::scoped_nsobject<DelayingGestureRecognizer> _delayingRecognizer;
}
- (instancetype)initWithEmbeddedView:(UIView*)embeddedView flutterView:(UIView*)flutterView {
- (instancetype)initWithEmbeddedView:(UIView*)embeddedView
flutterViewController:(UIViewController*)flutterViewController {
self = [super initWithFrame:embeddedView.frame];
if (self) {
self.multipleTouchEnabled = YES;
......@@ -372,7 +379,7 @@ void FlutterPlatformViewsController::EnsureGLOverlayInitialized(
ForwardingGestureRecognizer* forwardingRecognizer =
[[[ForwardingGestureRecognizer alloc] initWithTarget:self
flutterView:flutterView] autorelease];
flutterViewController:flutterViewController] autorelease];
_delayingRecognizer.reset([[DelayingGestureRecognizer alloc]
initWithTarget:self
......@@ -446,35 +453,37 @@ void FlutterPlatformViewsController::EnsureGLOverlayInitialized(
@implementation ForwardingGestureRecognizer {
// We can't dispatch events to the framework without this back pointer.
// This is a weak reference, the ForwardingGestureRecognizer is owned by the
// FlutterTouchInterceptingView which is strong referenced only by the FlutterView.
// FlutterTouchInterceptingView which is strong referenced only by the FlutterView,
// which is strongly referenced by the FlutterViewController.
// So this is safe as when FlutterView is deallocated the reference to ForwardingGestureRecognizer
// will go away.
UIView* _flutterView;
UIViewController* _flutterViewController;
// Counting the pointers that has started in one touch sequence.
NSInteger _currentTouchPointersCount;
}
- (instancetype)initWithTarget:(id)target flutterView:(UIView*)flutterView {
- (instancetype)initWithTarget:(id)target
flutterViewController:(UIViewController*)flutterViewController {
self = [super initWithTarget:target action:nil];
if (self) {
self.delegate = self;
_flutterView = flutterView;
_flutterViewController = flutterViewController;
_currentTouchPointersCount = 0;
}
return self;
}
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
[_flutterView touchesBegan:touches withEvent:event];
[_flutterViewController touchesBegan:touches withEvent:event];
_currentTouchPointersCount += touches.count;
}
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
[_flutterView touchesMoved:touches withEvent:event];
[_flutterViewController touchesMoved:touches withEvent:event];
}
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
[_flutterView touchesEnded:touches withEvent:event];
[_flutterViewController touchesEnded:touches withEvent:event];
_currentTouchPointersCount -= touches.count;
// Touches in one touch sequence are sent to the touchesEnded method separately if different
// fingers stop touching the screen at different time. So one touchesEnded method triggering does
......@@ -486,7 +495,7 @@ void FlutterPlatformViewsController::EnsureGLOverlayInitialized(
}
- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event {
[_flutterView touchesCancelled:touches withEvent:event];
[_flutterViewController touchesCancelled:touches withEvent:event];
_currentTouchPointersCount = 0;
self.state = UIGestureRecognizerStateFailed;
}
......
......@@ -18,7 +18,8 @@
// 1. Delay or prevent touch events from arriving the embedded view.
// 2. Dispatching all events that are hittested to the embedded view to the FlutterView.
@interface FlutterTouchInterceptingView : UIView
- (instancetype)initWithEmbeddedView:(UIView*)embeddedView flutterView:(UIView*)flutterView;
- (instancetype)initWithEmbeddedView:(UIView*)embeddedView
flutterViewController:(UIViewController*)flutterViewController;
// Stop delaying any active touch sequence (and let it arrive the embedded view).
- (void)releaseGesture;
......@@ -52,6 +53,8 @@ class FlutterPlatformViewsController {
void SetFlutterView(UIView* flutter_view);
void SetFlutterViewController(UIViewController* flutter_view_controller);
void RegisterViewFactory(NSObject<FlutterPlatformViewFactory>* factory, NSString* factoryId);
void SetFrameSize(SkISize frame_size);
......@@ -81,6 +84,7 @@ class FlutterPlatformViewsController {
private:
fml::scoped_nsobject<FlutterMethodChannel> channel_;
fml::scoped_nsobject<UIView> flutter_view_;
fml::scoped_nsobject<UIViewController> flutter_view_controller_;
std::map<std::string, fml::scoped_nsobject<NSObject<FlutterPlatformViewFactory>>> factories_;
std::map<int64_t, fml::scoped_nsobject<NSObject<FlutterPlatformView>>> views_;
std::map<int64_t, fml::scoped_nsobject<FlutterTouchInterceptingView>> touch_interceptors_;
......
......@@ -382,10 +382,12 @@ NSNotificationName const FlutterSemanticsUpdateNotification = @"FlutterSemantics
if (appeared) {
[self installSplashScreenViewCallback];
[_engine.get() platformViewsController] -> SetFlutterView(_flutterView.get());
[_engine.get() platformViewsController] -> SetFlutterViewController(self);
[_engine.get() platformView] -> NotifyCreated();
} else {
[_engine.get() platformView] -> NotifyDestroyed();
[_engine.get() platformViewsController] -> SetFlutterView(nullptr);
[_engine.get() platformViewsController] -> SetFlutterViewController(nullptr);
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册