Add a callback for iOS when the first Flutter frame is rendered (#6135)

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
This commit is contained in:
James D. Lin 2018-10-11 20:21:13 -07:00 committed by GitHub
parent 35ba11eb49
commit 3ffa362952
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 0 deletions

View File

@ -24,6 +24,14 @@ FLUTTER_EXPORT
- (void)handleStatusBarTouches:(UIEvent*)event;
/**
Registers a callback that will be invoked when the Flutter view has been rendered.
The callback will be fired only once.
Replaces an existing callback. Use a `nil` callback to unregister the existing one.
*/
- (void)setFlutterViewDidRenderCallback:(void (^)(void))callback;
/**
Returns the file name for the given asset.
The returned file name can be used to access the asset in the application's main bundle.

View File

@ -51,6 +51,7 @@
// setup a shell along with its platform view before the view has to appear.
fml::scoped_nsobject<FlutterView> _flutterView;
fml::scoped_nsobject<UIView> _splashScreenView;
fml::ScopedBlock<void (^)(void)> _flutterViewRenderedCallback;
UIInterfaceOrientationMask _orientationPreferences;
UIStatusBarStyle _statusBarStyle;
blink::ViewportMetrics _viewportMetrics;
@ -367,6 +368,10 @@
completion:^(BOOL finished) {
[_splashScreenView.get() removeFromSuperview];
_splashScreenView.reset();
if (_flutterViewRenderedCallback != nil) {
_flutterViewRenderedCallback.get()();
_flutterViewRenderedCallback.reset();
}
}];
}
@ -443,6 +448,10 @@
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
}
- (void)setFlutterViewDidRenderCallback:(void (^)(void))callback {
_flutterViewRenderedCallback.reset(callback, fml::OwnershipPolicy::Retain);
}
#pragma mark - Surface creation and teardown updates
- (void)surfaceUpdated:(BOOL)appeared {