[ContentPage] NavigationPage.BarBackgroundColorProperty and NavigationPage.BarTextColorProperty now properly assigns colors to modal navigation bars, including status bar, back button and toolbar icons. Removed old Android workarounds for modal toolbar coloring.#869
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR improves modal NavigationPage theming by making DUI ContentPage actively apply NavigationPage.BarBackgroundColorProperty / BarTextColorProperty (attached to the page) onto the hosting NavigationPage, and aligns Android/iOS status bar behavior with the effective navigation bar colors. It also removes prior Android toolbar tinting workarounds that conflicted with per-page modal colors.
Changes:
- Added cross-platform
ContentPagenavigation bar color proxying (with platform-specific hooks for status bar refresh). - Added iOS
ModalNavigationRendererto resolve modal status bar text style from navigation bar background luminosity. - Simplified Android modal toolbar/status bar coloring by removing hardcoded mappers/workarounds and introducing an “effective” status bar color resolution.
Reviewed changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
wiki/Layout & Navigation/Pages.md |
Documents how to set modal navigation bar colors via attached properties on ContentPage. |
src/library/DIPS.Mobile.UI/Components/Shell/Shell.cs |
Aligns Shell foreground color token with title text color token. |
src/library/DIPS.Mobile.UI/Components/Pages/ContentPage.cs |
Re-applies navigation bar colors during lifecycle; Android now uses effective status bar color resolution. |
src/library/DIPS.Mobile.UI/Components/Pages/ContentPage.Properties.cs |
Changes StatusBarColor API to nullable and updates docs to describe defaulting behavior. |
src/library/DIPS.Mobile.UI/Components/Pages/ContentPage.navigationbar.cs |
New shared logic to default and proxy page-attached nav bar colors to parent NavigationPage. |
src/library/DIPS.Mobile.UI/Components/Pages/Android/ContentPage.navigationbar.cs |
Android platform implementation: sets status bar color and resolves effective status bar color. |
src/library/DIPS.Mobile.UI/Components/Pages/iOS/ContentPage.navigationbar.cs |
iOS platform implementation: triggers status bar appearance refresh. |
src/library/DIPS.Mobile.UI/Components/Pages/dotnet/ContentPage.navigationbar.cs |
Stub for net10.0 target. |
src/library/DIPS.Mobile.UI/Components/Pages/iOS/ModalNavigationRenderer.cs |
New iOS renderer to compute modal status bar style from nav bar background color and refresh on back navigation. |
src/library/DIPS.Mobile.UI/API/Library/Android/StatusBarHandler.cs |
Uses the new effective status bar color resolution when applying overrides and modal window colors. |
src/library/DIPS.Mobile.UI/API/Library/Android/FragmentLifeCycleCallback.cs |
Removes modal toolbar tinting workaround previously forcing Shell foreground color. |
src/library/DIPS.Mobile.UI/API/Builder/iOS/AppHostBuilderExtensions.cs |
Registers ModalNavigationRenderer for NavigationPage on iOS. |
src/library/DIPS.Mobile.UI/API/Builder/Android/AppHostBuilderExtensions.cs |
Removes Android toolbar mapper workarounds and modernizes handler registrations. |
src/app/Playground/MainPage.xaml / src/app/Playground/MainPage.xaml.cs |
Adds navigation entries to new modal navigation bar samples. |
src/app/Playground/NavigationBarColorSample.xaml / .xaml.cs |
New playground sample for modal navigation bar background override. |
src/app/Playground/ModalNavigationBarBackNavigationSample/* |
New playground sample to validate nav bar color restoration across push/pop within a modal nav stack. |
src/app/Playground/VetleSamples/VetlePage.xaml |
Adds a toolbar item (likely to test toolbar coloring). |
CHANGELOG.md |
Adds a release note for the modal navigation bar color behavior change. |
haavamoa
approved these changes
May 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description of Change
Modal navigation bar color support
Consumers can set NavigationPage.BarBackgroundColorProperty and NavigationPage.BarTextColorProperty on a ContentPage to control the modal navigation bar colors. MAUI already supports these as attached properties on ContentPage, but has a bug where it never actually applies them to the NavigationPage — the values are stored but ignored. To work around this, ContentPage now reads the attached property values and explicitly sets them on the parent NavigationPage (navigationPage.BarBackgroundColor / navigationPage.BarTextColor). When not explicitly set by the consumer, colors default to the Shell navigation bar colors.
Usage in a modal page constructor:
Why OnParentSet
Colors are applied in OnParentSet (and re-applied in OnAppearing and OnHandlerChanged) because on iOS this is the earliest point where the parent NavigationPage is available. We read the attached property values from the ContentPage and proxy them to the NavigationPage directly, since MAUI does not do this itself.
New file structure
Navigation bar logic is extracted into dedicated partial files following the existing platform-specific pattern:
iOS status bar style (ModalNavigationRenderer)
A custom NavigationRenderer (ModalNavigationRenderer) is registered for NavigationPage on iOS. It overrides PreferredStatusBarStyle to resolve the status bar style from the current page's BarBackgroundColor luminosity — dark backgrounds get light status bar text and vice versa. It also subscribes to NavigationPage.Popped to refresh the status bar style after back-navigation transitions.
Removed Android ToolbarHandler mapper workarounds
The ToolbarHandler.Mapper.AppendToMapping workarounds for ToolbarItems and BackButtonVisible in AppHostBuilderExtensions.cs (Android) were removed. These mappers hardcoded toolbar icon and back button colors to Shell.ForegroundColorName, which broke modal pages with per-page BarTextColor. With colors now proxied directly to the NavigationPage, MAUI's built-in toolbar color propagation handles this correctly.
The SetColorsOnModal method in FragmentLifeCycleCallback was also removed for the same reason — it hardcoded modal toolbar icon tint to the Shell foreground color.
StatusBarColor is now nullable
StatusBarColor is changed from a non-nullable Color (defaulting to Shell background) to Color? (defaulting to null). When not explicitly set, the effective status bar color is resolved automatically:
This means the Android status bar automatically matches the navigation bar in modals without consumers needing to set StatusBarColor separately.
Shell.ForegroundColorName change
Changed from color_icon_action to color_text_default to align toolbar icon and text color with the title text color.
Todos