This PR breaks PlatformViewsController's construction dependency on FlutterView,
which allows making FlutterEngine its owner instead of
FlutterViewController.
Also renamed the FlutterScreenshotDelegate to FlutterViewEngineDelegate
which is FlutterView's delegate to the engine, and expanded it to
provide a view embedder.
This allows the framework to decide whether and when a touch event
sequence arrives to the embedded view. Which gives the framework the
ability to manage hit testing and gesture disambiguation for embedded
UIViews.
We achieve this by wrapping each embedded UIView with another UIView that has
a custom UIGestureRecognizer that delays touch events from being
delivered, and another UIGestureRecognizer that makes sure to let
Flutter know of events that are hit tested to the embedded view.
For flow to manipulate the embedded UIViews during the paint traversal
it needs some hook in PaintContext.
This PR introduces a ViewEmbeder interface that is implemented by the
iOS PlatformViewsController and plumbs it into PaintContext.
The ViewEmbedder interface is mainly a place holder at this point, as
this PR is focused on just the plumbing.
* Create FlutterEngine to manage a Shell to support maintaining execution state across instances of FlutterViewControllers
* Refactor PlatformViewIOS to support adding or removing a FlutterViewController dynamically
* Refactor FlutterDartHeadlessCodeRunner to implement FlutterEngine
* Refactor FlutterViewController to accept a FlutterEngine at initialization or to create one for backwards compatibility; any Shell related responsibilities are now passed through to the Engine instance
* Remove FlutterNavigationController (unused)
* Update all public Objective C doc comments to be consistent and formatable
* Add public documentation to all public headers
Adds a FlutterPlatformViewFactory protocol - a simple factory protocol to be implemented by plugins
that exposes a UIView for embedding in Flutter apps.
* Adds a FlutterPlatformView protocol, which is used to associate a
dispose callback with a `UIView` created by a FlutterPlatformViewFactory.
* Exposes a registerViewFactory method in FlutterPluginRegistrar.
* Implements the `flutter/platform_views` system channel on iOS, allowing
Dart code to ask for creation/destruction of UIViews.
According to the iOS docs, implementing
`- (id)insertDictationResultPlaceholder`
```Implementation of this method is optional but can be done when you want to provide a specific rectangle for the placeholder animation while the dictation results are being processed. ```
If you do not implement this method, UIKit will insert a default placeholder of 10 whitespace characters. By overriding this, no placeholder text will be inserted. If you implement the `insertDictationResultPlaceholder`, you must implement
`- (void)removeDictationResultPlaceholder:(id)placeholder willInsertResult:(BOOL)willInsertResult`
Add a `-[FlutterViewController setFlutterViewDidRenderCallback:]`
method on iOS so client applications can be notified when the Flutter
view has rendered. This can be used for add2app cases to determine
when to take an initial screenshot for comparisons in automated
tests.
The callback is expected to be an Objective-C block (or Swift
closure). I chose to support only a single callback because it's
much simpler (especially since it does not require a separate method
to unregister the callback), and it's not clear that there are use
cases that would justify additional complexity. Clients have the
flexibility to make their callback invoke other callbacks anyway.
I alternatively considered adding a `-[FlutterViewController
viewDidRenderFirstFlutterFrame]` method that clients could override
in a subclass, but using an Objective-C block seems more flexible and
less of a burden.
Fixes https://github.com/flutter/flutter/issues/20665
The touch mapper was a relic of a time when the pointer IDs had to be less
than 16. Not respecting the touch phase is getting in the way of clients that
fake their own touches. Turns out the AppDelegate also like to fake touches to
simulate status bar events. Now, except in cases where there is a specific
override in place, the UI touch phase is respected.