@@ -6,6 +6,7 @@ import type { View } from '..';
66import { ViewHelper } from './view-helper-common' ;
77import { SDK_VERSION } from '../../../../utils/constants' ;
88import { layout , Trace } from './view-helper-shared' ;
9+ import { ios as iosUtils , getWindow } from '../../../../utils' ;
910
1011export * from './view-helper-common' ;
1112export const AndroidHelper = 0 ;
@@ -97,6 +98,9 @@ class UILayoutViewController extends UIViewController {
9798 return ;
9899 }
99100
101+ // Ensure iOS re-queries `preferredStatusBarStyle` for this controller.
102+ IOSHelper . invalidateStatusBarAppearance ( this , 'UILayoutViewController.viewWillAppear' ) ;
103+
100104 IOSHelper . updateAutoAdjustScrollInsets ( this , owner ) ;
101105
102106 if ( ! owner . isLoaded && ! owner . parent ) {
@@ -112,6 +116,14 @@ class UILayoutViewController extends UIViewController {
112116 }
113117 }
114118
119+ // Forward status bar appearance to our content controller when available.
120+ // Without this, iOS may use this controller's own preferredStatusBarStyle,
121+ // which can be unrelated to the currently shown Page.
122+ // @ts -ignore
123+ public get childViewControllerForStatusBarStyle ( ) : UIViewController {
124+ return this . presentedViewController || this . childViewControllers ?. lastObject ;
125+ }
126+
115127 // Mind implementation for other controllers
116128 public traitCollectionDidChange ( previousTraitCollection : UITraitCollection ) : void {
117129 super . traitCollectionDidChange ( previousTraitCollection ) ;
@@ -213,6 +225,49 @@ export class IOSHelper {
213225 return view ;
214226 }
215227
228+ static invalidateStatusBarAppearance ( controller ?: UIViewController , reason = '' ) : void {
229+ try {
230+ if ( ! controller ) {
231+ const window = getWindow < UIWindow > ?. ( ) ;
232+ const rootController = window ?. rootViewController ;
233+ controller = rootController ? iosUtils . getVisibleViewController ( rootController ) : null ;
234+ }
235+
236+ if ( ! controller ) {
237+ if ( Trace . isEnabled ( ) ) {
238+ Trace . write ( `[StatusBar] invalidate skipped (no controller) reason=${ reason } ` , Trace . categories . NativeLifecycle ) ;
239+ }
240+ return ;
241+ }
242+
243+ const container = controller ;
244+ let child : UIViewController = null ;
245+ try {
246+ child = container . childViewControllerForStatusBarStyle ;
247+ } catch {
248+ child = null ;
249+ }
250+ if ( ! child ) {
251+ if ( container instanceof UINavigationController ) {
252+ child = container . topViewController ;
253+ } else if ( container instanceof UITabBarController ) {
254+ child = container . selectedViewController ;
255+ }
256+ }
257+
258+ // Always invalidate container and likely child.
259+ container . setNeedsStatusBarAppearanceUpdate ?.( ) ;
260+ child ?. setNeedsStatusBarAppearanceUpdate ?.( ) ;
261+
262+ // Also invalidate nav container if present.
263+ const nav = container instanceof UINavigationController ? container : container . navigationController ;
264+ nav ?. setNeedsStatusBarAppearanceUpdate ?.( ) ;
265+ nav ?. topViewController ?. setNeedsStatusBarAppearanceUpdate ?.( ) ;
266+ } catch ( e ) {
267+ Trace . write ( `[StatusBar] invalidate error: ${ e } ` , Trace . categories . Error , Trace . messageType . warn ) ;
268+ }
269+ }
270+
216271 static updateAutoAdjustScrollInsets ( controller : UIViewController , owner : View ) : void {
217272 if ( ! __VISIONOS__ && SDK_VERSION <= 10 ) {
218273 owner . _automaticallyAdjustsScrollViewInsets = false ;
0 commit comments