mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Add isDisplayingFlutterUI to FlutterViewController (flutter/engine#10816)
This commit is contained in:
parent
89f22f0144
commit
16c2058bf2
@ -130,6 +130,14 @@ FLUTTER_EXPORT
|
||||
*/
|
||||
- (id<FlutterPluginRegistry>)pluginRegistry;
|
||||
|
||||
/**
|
||||
* True if at least one frame has rendered and the ViewController has appeared.
|
||||
*
|
||||
* This property is reset to false when the ViewController disappears. It is
|
||||
* guaranteed to only alternate between true and false for observers.
|
||||
*/
|
||||
@property(nonatomic, readonly, getter=isDisplayingFlutterUI) BOOL displayingFlutterUI;
|
||||
|
||||
/**
|
||||
* Specifies the view to use as a splash screen. Flutter's rendering is asynchronous, so the first
|
||||
* frame rendered by the Flutter application might not immediately appear when theFlutter view is
|
||||
|
||||
@ -29,6 +29,7 @@ NSNotificationName const FlutterSemanticsUpdateNotification = @"FlutterSemantics
|
||||
// change. Unfortunately unless you have Werror turned on, incompatible pointers as arguments are
|
||||
// just a warning.
|
||||
@interface FlutterViewController () <FlutterBinaryMessenger>
|
||||
@property(nonatomic, readwrite, getter=isDisplayingFlutterUI) BOOL displayingFlutterUI;
|
||||
@end
|
||||
|
||||
@implementation FlutterViewController {
|
||||
@ -49,6 +50,8 @@ NSNotificationName const FlutterSemanticsUpdateNotification = @"FlutterSemantics
|
||||
NSMutableSet<NSNumber*>* _ongoingTouches;
|
||||
}
|
||||
|
||||
@synthesize displayingFlutterUI = _displayingFlutterUI;
|
||||
|
||||
#pragma mark - Manage and override all designated initializers
|
||||
|
||||
- (instancetype)initWithEngine:(FlutterEngine*)engine
|
||||
@ -263,7 +266,25 @@ NSNotificationName const FlutterSemanticsUpdateNotification = @"FlutterSemantics
|
||||
[self.view addSubview:splashScreenView];
|
||||
}
|
||||
|
||||
+ (BOOL)automaticallyNotifiesObserversOfDisplayingFlutterUI {
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)setDisplayingFlutterUI:(BOOL)displayingFlutterUI {
|
||||
if (_displayingFlutterUI != displayingFlutterUI) {
|
||||
if (displayingFlutterUI == YES) {
|
||||
if (!self.isViewLoaded || !self.view.window) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
[self willChangeValueForKey:@"displayingFlutterUI"];
|
||||
_displayingFlutterUI = displayingFlutterUI;
|
||||
[self didChangeValueForKey:@"displayingFlutterUI"];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)callViewRenderedCallback {
|
||||
self.displayingFlutterUI = YES;
|
||||
if (_flutterViewRenderedCallback != nil) {
|
||||
_flutterViewRenderedCallback.get()();
|
||||
_flutterViewRenderedCallback.reset();
|
||||
@ -395,6 +416,7 @@ NSNotificationName const FlutterSemanticsUpdateNotification = @"FlutterSemantics
|
||||
[_engine.get() platformViewsController] -> SetFlutterViewController(self);
|
||||
[_engine.get() platformView] -> NotifyCreated();
|
||||
} else {
|
||||
self.displayingFlutterUI = NO;
|
||||
[_engine.get() platformView] -> NotifyDestroyed();
|
||||
[_engine.get() platformViewsController] -> SetFlutterView(nullptr);
|
||||
[_engine.get() platformViewsController] -> SetFlutterViewController(nullptr);
|
||||
|
||||
@ -25,25 +25,31 @@
|
||||
}
|
||||
|
||||
- (void)testFirstFrameCallback {
|
||||
XCTestExpectation* firstFrameRendered = [self expectationWithDescription:@"firstFrameRendered"];
|
||||
|
||||
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
|
||||
[engine runWithEntrypoint:nil];
|
||||
self.flutterViewController = [[FlutterViewController alloc] initWithEngine:engine
|
||||
nibName:nil
|
||||
bundle:nil];
|
||||
__block BOOL shouldKeepRunning = YES;
|
||||
|
||||
XCTAssertFalse(self.flutterViewController.isDisplayingFlutterUI);
|
||||
|
||||
XCTestExpectation* displayingFlutterUIExpectation =
|
||||
[self keyValueObservingExpectationForObject:self.flutterViewController
|
||||
keyPath:@"displayingFlutterUI"
|
||||
expectedValue:@YES];
|
||||
displayingFlutterUIExpectation.assertForOverFulfill = YES;
|
||||
|
||||
[self.flutterViewController setFlutterViewDidRenderCallback:^{
|
||||
shouldKeepRunning = NO;
|
||||
[firstFrameRendered fulfill];
|
||||
}];
|
||||
|
||||
AppDelegate* appDelegate = (AppDelegate*)UIApplication.sharedApplication.delegate;
|
||||
UIViewController* rootVC = appDelegate.window.rootViewController;
|
||||
[rootVC presentViewController:self.flutterViewController animated:NO completion:nil];
|
||||
NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
|
||||
int countDownMs = 2000;
|
||||
while (shouldKeepRunning && countDownMs > 0) {
|
||||
[runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
|
||||
countDownMs -= 100;
|
||||
}
|
||||
XCTAssertGreaterThan(countDownMs, 0);
|
||||
|
||||
[self waitForExpectationsWithTimeout:30.0 handler:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user