| Flutter iOS Embedder |

FlutterPlatformViews_Internal.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERPLATFORMVIEWS_INTERNAL_H_
6 #define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERPLATFORMVIEWS_INTERNAL_H_
7
8 #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlatformViews.h"
9 #include "fml/task_runner.h"
10 #include "impeller/base/thread_safety.h"
11 #include "third_party/skia/include/core/SkRect.h"
12
13 #include <Metal/Metal.h>
14
15 #include "flutter/flow/surface.h"
16 #include "flutter/fml/memory/weak_ptr.h"
17 #include "flutter/fml/platform/darwin/scoped_nsobject.h"
18 #include "flutter/fml/trace_event.h"
19 #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterChannels.h"
20 #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlugin.h"
21 #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewResponder.h"
22 #import "flutter/shell/platform/darwin/ios/framework/Source/platform_views_controller.h"
23 #import "flutter/shell/platform/darwin/ios/ios_context.h"
24
25 @class FlutterTouchInterceptingView;
26
27 // A UIView that acts as a clipping mask for the |ChildClippingView|.
28 //
29 // On the [UIView drawRect:] method, this view performs a series of clipping operations and sets the
30 // alpha channel to the final resulting area to be 1; it also sets the "clipped out" area's alpha
31 // channel to be 0.
32 //
33 // When a UIView sets a |FlutterClippingMaskView| as its `maskView`, the alpha channel of the UIView
34 // is replaced with the alpha channel of the |FlutterClippingMaskView|.
35 @interface FlutterClippingMaskView : UIView
36
37 - (instancetype)initWithFrame:(CGRect)frame screenScale:(CGFloat)screenScale;
38
39 - (void)reset;
40
41 // Adds a clip rect operation to the queue.
42 //
43 // The `clipSkRect` is transformed with the `matrix` before adding to the queue.
44 - (void)clipRect:(const SkRect&)clipSkRect matrix:(const SkMatrix&)matrix;
45
46 // Adds a clip rrect operation to the queue.
47 //
48 // The `clipSkRRect` is transformed with the `matrix` before adding to the queue.
49 - (void)clipRRect:(const SkRRect&)clipSkRRect matrix:(const SkMatrix&)matrix;
50
51 // Adds a clip path operation to the queue.
52 //
53 // The `path` is transformed with the `matrix` before adding to the queue.
54 - (void)clipPath:(const SkPath&)path matrix:(const SkMatrix&)matrix;
55
56 @end
57
58 // A pool that provides |FlutterClippingMaskView|s.
59 //
60 // The pool has a capacity that can be set in the initializer.
61 // When requesting a FlutterClippingMaskView, the pool will first try to reuse an available maskView
62 // in the pool. If there are none available, a new FlutterClippingMaskView is constructed. If the
63 // capacity is reached, the newly constructed FlutterClippingMaskView is not added to the pool.
64 //
65 // Call |insertViewToPoolIfNeeded:| to return a maskView to the pool.
66 @interface FlutterClippingMaskViewPool : NSObject
67
68 // Initialize the pool with `capacity`. When the `capacity` is reached, a FlutterClippingMaskView is
69 // constructed when requested, and it is not added to the pool.
70 - (instancetype)initWithCapacity:(NSInteger)capacity;
71
72 // Reuse a maskView from the pool, or allocate a new one.
73 - (FlutterClippingMaskView*)getMaskViewWithFrame:(CGRect)frame;
74
75 // Insert the `maskView` into the pool.
76 - (void)insertViewToPoolIfNeeded:(FlutterClippingMaskView*)maskView;
77
78 @end
79
80 // An object represents a blur filter.
81 //
82 // This object produces a `backdropFilterView`.
83 // To blur a View, add `backdropFilterView` as a subView of the View.
84 @interface PlatformViewFilter : NSObject
85
86 // Determines the rect of the blur effect in the coordinate system of `backdropFilterView`'s
87 // parentView.
88 @property(nonatomic, readonly) CGRect frame;
89
90 // Determines the blur intensity.
91 //
92 // It is set as the value of `inputRadius` of the `gaussianFilter` that is internally used.
93 @property(nonatomic, readonly) CGFloat blurRadius;
94
95 // This is the view to use to blur the PlatformView.
96 //
97 // It is a modified version of UIKit's `UIVisualEffectView`.
98 // The inputRadius can be customized and it doesn't add any color saturation to the blurred view.
99 @property(nonatomic, readonly) UIVisualEffectView* backdropFilterView;
100
101 // For testing only.
102 + (void)resetPreparation;
103
104 - (instancetype)init NS_UNAVAILABLE;
105
106 // Initialize the filter object.
107 //
108 // The `frame` determines the rect of the blur effect in the coordinate system of
109 // `backdropFilterView`'s parentView. The `blurRadius` determines the blur intensity. It is set as
110 // the value of `inputRadius` of the `gaussianFilter` that is internally used. The
111 // `UIVisualEffectView` is the view that is used to add the blur effects. It is modified to become
112 // `backdropFilterView`, which better supports the need of Flutter.
113 //
114 // Note: if the implementation of UIVisualEffectView changes in a way that affects the
115 // implementation in `PlatformViewFilter`, this method will return nil.
116 - (instancetype)initWithFrame:(CGRect)frame
117 blurRadius:(CGFloat)blurRadius
118 visualEffectView:(UIVisualEffectView*)visualEffectView NS_DESIGNATED_INITIALIZER;
119
120 @end
121
122 // The parent view handles clipping to its subViews.
123 @interface ChildClippingView : UIView
124
125 // Applies blur backdrop filters to the ChildClippingView with blur values from
126 // filters.
127 - (void)applyBlurBackdropFilters:(NSArray<PlatformViewFilter*>*)filters;
128
129 // For testing only.
130 - (NSMutableArray*)backdropFilterSubviews;
131 @end
132
133 // A UIView that is used as the parent for embedded UIViews.
134 //
135 // This view has 2 roles:
136 // 1. Delay or prevent touch events from arriving the embedded view.
137 // 2. Dispatching all events that are hittested to the embedded view to the FlutterView.
138 @interface FlutterTouchInterceptingView : UIView
139 - (instancetype)initWithEmbeddedView:(UIView*)embeddedView
140 platformViewsController:
141 (fml::WeakPtr<flutter::PlatformViewsController>)platformViewsController
142 gestureRecognizersBlockingPolicy:
143 (FlutterPlatformViewGestureRecognizersBlockingPolicy)blockingPolicy;
144
145 // Stop delaying any active touch sequence (and let it arrive the embedded view).
146 - (void)releaseGesture;
147
148 // Prevent the touch sequence from ever arriving to the embedded view.
149 - (void)blockGesture;
150
151 // Get embedded view
152 - (UIView*)embeddedView;
153
154 // Sets flutterAccessibilityContainer as this view's accessibilityContainer.
155 @property(nonatomic, retain) id flutterAccessibilityContainer;
156 @end
157
158 @interface UIView (FirstResponder)
159 // Returns YES if a view or any of its descendant view is the first responder. Returns NO otherwise.
160 @property(nonatomic, readonly) BOOL flt_hasFirstResponderInViewHierarchySubtree;
161 @end
162
163 // This recognizer delays touch events from being dispatched to the responder chain until it failed
164 // recognizing a gesture.
165 //
166 // We only fail this recognizer when asked to do so by the Flutter framework (which does so by
167 // invoking an acceptGesture method on the platform_views channel). And this is how we allow the
168 // Flutter framework to delay or prevent the embedded view from getting a touch sequence.
169 @interface FlutterDelayingGestureRecognizer : UIGestureRecognizer <UIGestureRecognizerDelegate>
170
171 // Indicates that if the `FlutterDelayingGestureRecognizer`'s state should be set to
172 // `UIGestureRecognizerStateEnded` during next `touchesEnded` call.
173 @property(nonatomic) BOOL shouldEndInNextTouchesEnded;
174
175 // Indicates that the `FlutterDelayingGestureRecognizer`'s `touchesEnded` has been invoked without
176 // setting the state to `UIGestureRecognizerStateEnded`.
177 @property(nonatomic) BOOL touchedEndedWithoutBlocking;
178
179 @property(nonatomic, readonly) UIGestureRecognizer* forwardingRecognizer;
180
181 - (instancetype)initWithTarget:(id)target
182 action:(SEL)action
183 forwardingRecognizer:(UIGestureRecognizer*)forwardingRecognizer;
184 @end
185
186 // While the FlutterDelayingGestureRecognizer is preventing touches from hitting the responder chain
187 // the touch events are not arriving to the FlutterView (and thus not arriving to the Flutter
188 // framework). We use this gesture recognizer to dispatch the events directly to the FlutterView
189 // while during this phase.
190 //
191 // If the Flutter framework decides to dispatch events to the embedded view, we fail the
192 // FlutterDelayingGestureRecognizer which sends the events up the responder chain. But since the
193 // events are handled by the embedded view they are not delivered to the Flutter framework in this
194 // phase as well. So during this phase as well the ForwardingGestureRecognizer dispatched the events
195 // directly to the FlutterView.
196 @interface ForwardingGestureRecognizer : UIGestureRecognizer <UIGestureRecognizerDelegate>
197 - (instancetype)initWithTarget:(id)target
198 platformViewsController:
199 (fml::WeakPtr<flutter::PlatformViewsController>)platformViewsController;
200 @end
201
202 #endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERPLATFORMVIEWS_INTERNAL_H_
-[FlutterTouchInterceptingView embeddedView]
UIView * embeddedView()
FlutterPlatformViews.h
platform_views_controller.h
FlutterDelayingGestureRecognizer
Definition: FlutterPlatformViews_Internal.h:169
FlutterTouchInterceptingView::flutterAccessibilityContainer
id flutterAccessibilityContainer
Definition: FlutterPlatformViews_Internal.h:155
PlatformViewFilter::frame
CGRect frame
Definition: FlutterPlatformViews_Internal.h:88
ForwardingGestureRecognizer
Definition: FlutterPlatformViews_Internal.h:196
FlutterChannels.h
initWithFrame
instancetype initWithFrame
Definition: FlutterTextInputPlugin.h:172
-[ChildClippingView backdropFilterSubviews]
NSMutableArray * backdropFilterSubviews()
Definition: FlutterPlatformViews_Internal.mm:181
FlutterPlugin.h
PlatformViewFilter::blurRadius
CGFloat blurRadius
Definition: FlutterPlatformViews_Internal.h:93
-[FlutterTouchInterceptingView releaseGesture]
void releaseGesture()
Definition: FlutterPlatformViews_Internal.mm:552
-[PlatformViewFilter NS_UNAVAILABLE]
instancetype NS_UNAVAILABLE()
FlutterViewResponder.h
-[FlutterClippingMaskView reset]
void reset()
Definition: FlutterPlatformViews_Internal.mm:234
PlatformViewFilter::backdropFilterView
UIVisualEffectView * backdropFilterView
Definition: FlutterPlatformViews_Internal.h:99
flutter
Definition: accessibility_bridge.h:28
FlutterPlatformViewGestureRecognizersBlockingPolicy
FlutterPlatformViewGestureRecognizersBlockingPolicy
Definition: FlutterPlugin.h:252
FlutterClippingMaskViewPool
Definition: FlutterPlatformViews_Internal.h:66
-[FlutterTouchInterceptingView blockGesture]
void blockGesture()
Definition: FlutterPlatformViews_Internal.mm:556
UIView(FirstResponder)
Definition: FlutterPlatformViews_Internal.h:158
ChildClippingView
Definition: FlutterPlatformViews_Internal.h:123
+[PlatformViewFilter resetPreparation]
void resetPreparation()
Definition: FlutterPlatformViews_Internal.mm:78
PlatformViewFilter
Definition: FlutterPlatformViews_Internal.h:84
ios_context.h
FlutterTouchInterceptingView
Definition: FlutterPlatformViews_Internal.h:138
FlutterClippingMaskView
Definition: FlutterPlatformViews_Internal.h:35