Skip to content

[release/11.0.1xx-preview7] Forward status bar style through NavigationPage handler - #37047

Merged
PureWeen merged 2 commits into
release/11.0.1xx-preview7from
kubaflo/fix-preview7-navigation-statusbar-style
Aug 3, 2026
Merged

[release/11.0.1xx-preview7] Forward status bar style through NavigationPage handler#37047
PureWeen merged 2 commits into
release/11.0.1xx-preview7from
kubaflo/fix-preview7-navigation-statusbar-style

Conversation

@kubaflo

@kubaflo kubaflo commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!

Description

The new iOS NavigationViewHandler forwards status-bar hidden queries through its navigation-controller and parenting-controller layers, but does not forward status-bar style queries. UIKit therefore resolves PreferredStatusBarStyle on the navigation controller and returns Default instead of the current page style.

Forward ChildViewControllerForStatusBarStyle through both handler layers, matching the old NavigationRenderer behavior. The existing StatusBarThemeFlowsThroughRootController(NavigationPage) device test covers the regression.

Failure evidence

Device build 1537360 failed the same test on all four iOS Mono/CoreCLR and Xcode queue combinations. Other root page types passed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 9be49656-7117-4235-9d96-404779ab6b16
Copilot AI review requested due to automatic review settings August 3, 2026 17:17
@kubaflo
kubaflo temporarily deployed to copilot-pat-pool August 3, 2026 17:17 — with GitHub Actions Inactive
@kubaflo

kubaflo commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

/azp run

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 37047

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 37047"

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
There may be pipelines that require an authorized user to comment /azp run to run.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes an iOS behavior regression in the new NavigationViewHandler stack by ensuring UIKit can resolve PreferredStatusBarStyle from the current page’s view controller (via the same navigation-controller / parenting-controller forwarding that already exists for status-bar hidden queries).

Changes:

  • Forward ChildViewControllerForStatusBarStyle() from the internal MauiNavigationController to the current top view controller (iOS-only).
  • Forward ChildViewControllerForStatusBarStyle() from the NavigationView handler’s parenting controller down to the child handler’s ViewController (iOS-only).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/Core/src/Platform/iOS/NavigationControllerManager/NavigationControllerManager.cs Adds iOS-only forwarding for ChildViewControllerForStatusBarStyle() so UINavigationController status bar style queries reach the active page controller.
src/Controls/src/Core/Platform/iOS/NavigationViewHandlerToolbarHelper.cs Adds iOS-only forwarding for ChildViewControllerForStatusBarStyle() from the parenting controller to the child handler’s view controller.

@PureWeen

PureWeen commented Aug 3, 2026

Copy link
Copy Markdown
Member

Independent verification found the same root cause and fix shape before comparing this PR:

  • MauiNavigationController only delegated ChildViewControllerForStatusBarHidden to its cached top controller, so style resolution stopped at the navigation controller.
  • NavigationHandlerParentingViewController likewise delegated hidden-state queries but not style queries, so both links are required to reach PageViewController.PreferredStatusBarStyle().
  • The legacy NavigationRenderer path already delegates ChildViewControllerForStatusBarStyle directly to the current page controller.

Local focused evidence on an iOS 26.5 simulator (Category=Window):

  • Without the two overrides: 11/12 passed; only StatusBarThemeFlowsThroughRootController(typeof(NavigationPage)) failed, expected Default, actual DarkContent.
  • With the two overrides: 12/12 passed, including all five root-page variants.

This matches the Preview 7 CI signature and confirms the existing test catches the product regression. One minor lifecycle note: the parenting-controller override here falls back to this when its child handler/controller is unavailable. That mirrors the existing hidden-state override, but returning self from ChildViewControllerForStatusBarStyle can form a delegation cycle during transient setup/teardown. A base fallback (?? base.ChildViewControllerForStatusBarStyle()!) avoids that edge while preserving the normal path; worth considering before merge.

Return base.ChildViewControllerForStatusBarStyle() when no child handler
view controller is available, matching the sibling override in the wrapped
controller and avoiding a potential status-bar-style delegation cycle from
returning `this`.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d00747b7-96f3-4e7a-8dfb-e3a48db04b2d
Copilot AI review requested due to automatic review settings August 3, 2026 18:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/Core/src/Platform/iOS/NavigationControllerManager/NavigationControllerManager.cs:242

  • Avoid null-forgiving on base.ChildViewControllerForStatusBarStyle(). Since the base implementation can legally return null, prefer an explicit fallback (e.g., ?? this) so this override never returns null and the behavior is clear under nullable reference types.
                    return vc;
                }
                return base.ChildViewControllerForStatusBarStyle()!;
            }

src/Controls/src/Core/Platform/iOS/NavigationViewHandlerToolbarHelper.cs:118

  • Avoid using null-forgiving on base.ChildViewControllerForStatusBarStyle(). The UIKit override is allowed to return null, but this method is declared non-nullable here; returning the base value with ! can mask a null return and makes the intent unclear. Prefer returning this when there is no child VC, matching the existing StatusBarHidden implementation.
#if !MACCATALYST
        public override UIViewController ChildViewControllerForStatusBarStyle() =>
            (Child?.Handler as IPlatformViewHandler)?.ViewController ?? base.ChildViewControllerForStatusBarStyle()!;

@PureWeen

PureWeen commented Aug 3, 2026

Copy link
Copy Markdown
Member

Follow-up after forcing the runner onto the exact iOS 18.5 simulator (3DFA6689-8F0F-4528-9EAD-0B00150643E9, reported by XHarness as deviceOsVersion: 18.5): the patched Category=Window run passed 12/12, with all five StatusBarThemeFlowsThroughRootController variants passing and XHarness exit code 0.

So the available local matrix is now:

Runtime Without fix With fix
iOS 18.5 CI build 1537360: NavigationPage fails (BlackTranslucent vs Default) Local: 12/12 Window tests pass
iOS 26.5 Local: 11/12, NavigationPage fails (Default vs DarkContent) Local: 12/12 Window tests pass

Correction to my earlier fallback note: after a second lifecycle review, ?? this is consistent with the sibling hidden/home-indicator delegation and is not a blocker. When the child VC is transiently unavailable, both this and the base-null fallback resolve to the wrapper's own default style; keeping this minimizes divergence from the existing controller pattern.

One runner quirk: Run-DeviceTests.ps1 aggregates stale prior log counts in its final human-readable summary, but the authoritative current XHarness block and in-app execution summary both report 12 passed, 0 failed, exit code 0.

@PureWeen

PureWeen commented Aug 3, 2026

Copy link
Copy Markdown
Member

CI follow-up for maui-pr-devicetests build 1537739:

  • Run DeviceTests iOS (Mono) succeeded.
  • Run DeviceTests iOS (CoreCLR) succeeded.
  • ✅ MacCatalyst succeeded.
  • ❌ Android Mono/CoreCLR are unrelated to this iOS-only diff:
    • Core device tests: only the two StatusBarThemeAppliesWhenHandlerConnects theories fail because WindowHandler.CreatePlatformElement() throws MauiContext did not have a valid window (2957 passed, 2 failed, 72 skipped in each runtime). This is the separate setup issue already seen in Preview 7 build 1537360.
    • Controls device tests: exit 80 app crash; one captured crash is the unrelated ShellItemWrapperFragment native-handle activation failure.

The relevant shipping matrices are therefore green in CI on the original fix commit, consistent with the focused local iOS 18.5 and 26.5 runs. Requesting a fresh device run below because the PR head changed afterward (fallback-only adjustment).

@PureWeen

PureWeen commented Aug 3, 2026

Copy link
Copy Markdown
Member

/azp run maui-pr-devicetests

@kubaflo

kubaflo commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

@PureWeen thanks for the review. Applied the suggestion in 838e913ChildViewControllerForStatusBarStyle() now falls back to base.ChildViewControllerForStatusBarStyle()! instead of this when there's no child handler view controller. That matches the sibling override inside the wrapped controller and avoids the potential status-bar-style delegation cycle from returning this. Ready for another look 🙏

@kubaflo

kubaflo commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

/azp run maui-pr-devicetests

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

1 similar comment
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@kubaflo

kubaflo commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

@PureWeen current head 838e913fcf is now proven against the original regression in device build 1537895:

  • iOS 18 CoreCLR Helix job fec7ad6c-6483-4bba-b5e7-43ea7c2e7c73: 9/9 work items passed.
  • iOS 26 CoreCLR Helix job fb7e67cd-577d-4011-a11f-9997d4ace1f3: 9/9 work items passed.
  • In both Controls.DeviceTests-General result files, all five StatusBarThemeFlowsThroughRootController cases passed, including the failing NavigationPage case.

The separate Mono build failure is the unrelated Graphics UIImageExtensions.ScaleImage CA1416 blocker, isolated in #37057. Please merge #37047 when review/check policy permits.

@PureWeen
PureWeen merged commit 2013a58 into release/11.0.1xx-preview7 Aug 3, 2026
36 of 40 checks passed
@PureWeen
PureWeen deleted the kubaflo/fix-preview7-navigation-statusbar-style branch August 3, 2026 21:00
@github-actions github-actions Bot added this to the .NET 11.0-preview7 milestone Aug 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants