mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
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.
This commit is contained in:
parent
710e9edda6
commit
0bc6dc9746
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user