Skip to content

Commit

Permalink
Fix not being able to hide iOS status bar via setEnabledSystemUIMode (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
LinXunFeng authored Nov 23, 2023
1 parent 5733891 commit bec0dac
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@
using namespace flutter;

static void SetStatusBarHiddenForSharedApplication(BOOL hidden) {
#if APPLICATION_EXTENSION_API_ONLY
#if not APPLICATION_EXTENSION_API_ONLY
[UIApplication sharedApplication].statusBarHidden = hidden;
#else
FML_LOG(WARNING) << "Application based status bar styling is not available in app extension.";
#endif
}

static void SetStatusBarStyleForSharedApplication(UIStatusBarStyle style) {
#if APPLICATION_EXTENSION_API_ONLY
#if not APPLICATION_EXTENSION_API_ONLY
// Note: -[UIApplication setStatusBarStyle] is deprecated in iOS9
// in favor of delegating to the view controller.
[[UIApplication sharedApplication] setStatusBarStyle:style];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -408,4 +408,93 @@ - (void)testViewControllerBasedStatusBarHiddenUpdate {
[bundleMock stopMocking];
}

- (void)testStatusBarHiddenUpdate {
id bundleMock = OCMPartialMock([NSBundle mainBundle]);
OCMStub([bundleMock objectForInfoDictionaryKey:@"UIViewControllerBasedStatusBarAppearance"])
.andReturn(@NO);
id mockApplication = OCMClassMock([UIApplication class]);
OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);

// Enabling system UI overlays to update status bar.
FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
[engine runWithEntrypoint:nil];
FlutterViewController* flutterViewController =
[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);

// Update to hidden.
FlutterPlatformPlugin* plugin = [engine platformPlugin];

XCTestExpectation* enableSystemUIOverlaysCalled =
[self expectationWithDescription:@"setEnabledSystemUIOverlays"];
FlutterResult resultSet = ^(id result) {
[enableSystemUIOverlaysCalled fulfill];
};
FlutterMethodCall* methodCallSet =
[FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setEnabledSystemUIOverlays"
arguments:@[ @"SystemUiOverlay.bottom" ]];
[plugin handleMethodCall:methodCallSet result:resultSet];
[self waitForExpectationsWithTimeout:1 handler:nil];
#if not APPLICATION_EXTENSION_API_ONLY
OCMVerify([mockApplication setStatusBarHidden:YES]);
#endif

// Update to shown.
XCTestExpectation* enableSystemUIOverlaysCalled2 =
[self expectationWithDescription:@"setEnabledSystemUIOverlays"];
FlutterResult resultSet2 = ^(id result) {
[enableSystemUIOverlaysCalled2 fulfill];
};
FlutterMethodCall* methodCallSet2 =
[FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setEnabledSystemUIOverlays"
arguments:@[ @"SystemUiOverlay.top" ]];
[plugin handleMethodCall:methodCallSet2 result:resultSet2];
[self waitForExpectationsWithTimeout:1 handler:nil];
#if not APPLICATION_EXTENSION_API_ONLY
OCMVerify([mockApplication setStatusBarHidden:NO]);
#endif

[flutterViewController deregisterNotifications];
[mockApplication stopMocking];
[bundleMock stopMocking];
}

- (void)testStatusBarStyle {
id bundleMock = OCMPartialMock([NSBundle mainBundle]);
OCMStub([bundleMock objectForInfoDictionaryKey:@"UIViewControllerBasedStatusBarAppearance"])
.andReturn(@NO);
id mockApplication = OCMClassMock([UIApplication class]);
OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);

FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
[engine runWithEntrypoint:nil];
FlutterViewController* flutterViewController =
[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
std::unique_ptr<fml::WeakNSObjectFactory<FlutterEngine>> _weakFactory =
std::make_unique<fml::WeakNSObjectFactory<FlutterEngine>>(engine);
XCTAssertFalse(flutterViewController.prefersStatusBarHidden);

FlutterPlatformPlugin* plugin = [engine platformPlugin];

XCTestExpectation* enableSystemUIModeCalled =
[self expectationWithDescription:@"setSystemUIOverlayStyle"];
FlutterResult resultSet = ^(id result) {
[enableSystemUIModeCalled fulfill];
};
FlutterMethodCall* methodCallSet =
[FlutterMethodCall methodCallWithMethodName:@"SystemChrome.setSystemUIOverlayStyle"
arguments:@{@"statusBarBrightness" : @"Brightness.dark"}];
[plugin handleMethodCall:methodCallSet result:resultSet];
[self waitForExpectationsWithTimeout:1 handler:nil];

#if not APPLICATION_EXTENSION_API_ONLY
OCMVerify([mockApplication setStatusBarStyle:UIStatusBarStyleLightContent]);
#endif

[flutterViewController deregisterNotifications];
[mockApplication stopMocking];
[bundleMock stopMocking];
}

@end

0 comments on commit bec0dac

Please sign in to comment.