-
Notifications
You must be signed in to change notification settings - Fork 6k
[ios] view controller based status bar #42643
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,6 +35,19 @@ | |
|
|
||
| using namespace flutter; | ||
|
|
||
| @interface FlutterPlatformPlugin () | ||
|
|
||
| /** | ||
| * @brief Whether the status bar appearance is based on the style preferred for this ViewController. | ||
| * | ||
| * The default value is true. | ||
| * Explicitly add `UIViewControllerBasedStatusBarAppearance` as `false` in | ||
| * info.plist makes this value to be false. | ||
| */ | ||
| @property(nonatomic, assign) BOOL enableViewControllerBasedStatusBarAppearance; | ||
|
stuartmorgan-g marked this conversation as resolved.
|
||
|
|
||
| @end | ||
|
|
||
| @implementation FlutterPlatformPlugin { | ||
| fml::WeakPtr<FlutterEngine> _engine; | ||
| // Used to detect whether this device has live text input ability or not. | ||
|
|
@@ -47,6 +60,9 @@ - (instancetype)initWithEngine:(fml::WeakPtr<FlutterEngine>)engine { | |
|
|
||
| if (self) { | ||
| _engine = engine; | ||
| NSNumber* infoValue = [[NSBundle mainBundle] | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code (the next line, specifically) will crash if someone puts the wrong key type in their Info.plist. Since that's a developer error that's probably okay, but it might be nice to check the type and log (in debug only) a clear error message if it's wrong.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
| objectForInfoDictionaryKey:@"UIViewControllerBasedStatusBarAppearance"]; | ||
| _enableViewControllerBasedStatusBarAppearance = (infoValue == nil || [infoValue boolValue]); | ||
|
stuartmorgan-g marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| return self; | ||
|
|
@@ -158,14 +174,7 @@ - (void)setSystemChromeApplicationSwitcherDescription:(NSDictionary*)object { | |
| } | ||
|
|
||
| - (void)setSystemChromeEnabledSystemUIOverlays:(NSArray*)overlays { | ||
| // Checks if the top status bar should be visible. This platform ignores all | ||
| // other overlays | ||
|
|
||
| // We opt out of view controller based status bar visibility since we want | ||
| // to be able to modify this on the fly. The key used is | ||
| // UIViewControllerBasedStatusBarAppearance | ||
| [UIApplication sharedApplication].statusBarHidden = | ||
| ![overlays containsObject:@"SystemUiOverlay.top"]; | ||
| BOOL statusBarShouldBeHidden = ![overlays containsObject:@"SystemUiOverlay.top"]; | ||
| if ([overlays containsObject:@"SystemUiOverlay.bottom"]) { | ||
| [[NSNotificationCenter defaultCenter] | ||
| postNotificationName:FlutterViewControllerShowHomeIndicator | ||
|
|
@@ -175,26 +184,36 @@ - (void)setSystemChromeEnabledSystemUIOverlays:(NSArray*)overlays { | |
| postNotificationName:FlutterViewControllerHideHomeIndicator | ||
| object:nil]; | ||
| } | ||
| if (self.enableViewControllerBasedStatusBarAppearance) { | ||
| [_engine.get() viewController].flutterPrefersStatusBarHidden = statusBarShouldBeHidden; | ||
| } else { | ||
| // Checks if the top status bar should be visible. This platform ignores all | ||
| // other overlays | ||
|
|
||
| // We opt out of view controller based status bar visibility since we want | ||
| // to be able to modify this on the fly. The key used is | ||
| // UIViewControllerBasedStatusBarAppearance. | ||
| [UIApplication sharedApplication].statusBarHidden = statusBarShouldBeHidden; | ||
| } | ||
| } | ||
|
|
||
| - (void)setSystemChromeEnabledSystemUIMode:(NSString*)mode { | ||
| // Checks if the top status bar should be visible, reflected by edge to edge setting. This | ||
| // platform ignores all other system ui modes. | ||
|
|
||
| // We opt out of view controller based status bar visibility since we want | ||
| // to be able to modify this on the fly. The key used is | ||
| // UIViewControllerBasedStatusBarAppearance | ||
| [UIApplication sharedApplication].statusBarHidden = | ||
| ![mode isEqualToString:@"SystemUiMode.edgeToEdge"]; | ||
| if ([mode isEqualToString:@"SystemUiMode.edgeToEdge"]) { | ||
| [[NSNotificationCenter defaultCenter] | ||
| postNotificationName:FlutterViewControllerShowHomeIndicator | ||
| object:nil]; | ||
| BOOL edgeToEdge = [mode isEqualToString:@"SystemUiMode.edgeToEdge"]; | ||
| if (self.enableViewControllerBasedStatusBarAppearance) { | ||
| [_engine.get() viewController].flutterPrefersStatusBarHidden = !edgeToEdge; | ||
| } else { | ||
| [[NSNotificationCenter defaultCenter] | ||
| postNotificationName:FlutterViewControllerHideHomeIndicator | ||
| object:nil]; | ||
| // Checks if the top status bar should be visible, reflected by edge to edge setting. This | ||
| // platform ignores all other system ui modes. | ||
|
|
||
| // We opt out of view controller based status bar visibility since we want | ||
| // to be able to modify this on the fly. The key used is | ||
| // UIViewControllerBasedStatusBarAppearance. | ||
| [UIApplication sharedApplication].statusBarHidden = !edgeToEdge; | ||
| } | ||
| [[NSNotificationCenter defaultCenter] | ||
| postNotificationName:edgeToEdge ? FlutterViewControllerShowHomeIndicator | ||
| : FlutterViewControllerHideHomeIndicator | ||
| object:nil]; | ||
| } | ||
|
|
||
| - (void)restoreSystemChromeSystemUIOverlays { | ||
|
|
@@ -220,19 +239,15 @@ - (void)setSystemChromeSystemUIOverlayStyle:(NSDictionary*)message { | |
| return; | ||
| } | ||
|
|
||
| NSNumber* infoValue = [[NSBundle mainBundle] | ||
| objectForInfoDictionaryKey:@"UIViewControllerBasedStatusBarAppearance"]; | ||
| Boolean delegateToViewController = (infoValue == nil || [infoValue boolValue]); | ||
|
|
||
| if (delegateToViewController) { | ||
| // This notification is respected by the iOS embedder | ||
| if (self.enableViewControllerBasedStatusBarAppearance) { | ||
| // This notification is respected by the iOS embedder. | ||
| [[NSNotificationCenter defaultCenter] | ||
| postNotificationName:@(kOverlayStyleUpdateNotificationName) | ||
| object:nil | ||
| userInfo:@{@(kOverlayStyleUpdateNotificationKey) : @(statusBarStyle)}]; | ||
| } else { | ||
| // Note: -[UIApplication setStatusBarStyle] is deprecated in iOS9 | ||
| // in favor of delegating to the view controller | ||
| // in favor of delegating to the view controller. | ||
| [[UIApplication sharedApplication] setStatusBarStyle:statusBarStyle]; | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,6 +39,16 @@ typedef NS_ENUM(NSInteger, FlutterKeyboardMode) { | |
| @property(nonatomic, readonly) BOOL isPresentingViewController; | ||
| @property(nonatomic, readonly) BOOL isVoiceOverRunning; | ||
| @property(nonatomic, retain) FlutterKeyboardManager* keyboardManager; | ||
|
|
||
| /** | ||
| * @brief Whether the status bar is preferred hidden. | ||
| * | ||
| * The |UIViewController:prefersStatusBarHidden| of this ViewController is overriden and | ||
| * returns `flutterPrefersStatusBarHidden`. This is ignored when | ||
| * `UIViewControllerBasedStatusBarAppearance` in info.plist of the app project is `false`. | ||
| */ | ||
| @property(nonatomic, assign) BOOL flutterPrefersStatusBarHidden; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looking at the structure again here... couldn't you just redeclare
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. I still kept the local var's name to be _flutterPrefersStatusBarHidden so it is clearer that the getter and setter are overridden. |
||
|
|
||
| - (fml::WeakPtr<FlutterViewController>)getWeakPtr; | ||
| - (std::shared_ptr<flutter::FlutterPlatformViewsController>&)platformViewsController; | ||
| - (FlutterRestorationPlugin*)restorationPlugin; | ||
|
|
@@ -53,6 +63,7 @@ typedef NS_ENUM(NSInteger, FlutterKeyboardMode) { | |
| - (void)addInternalPlugins; | ||
| - (void)deregisterNotifications; | ||
| - (int32_t)accessibilityFlags; | ||
|
|
||
| @end | ||
|
|
||
| #endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERVIEWCONTROLLER_INTERNAL_H_ | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: "YES", not "true".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done