diff --git a/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs b/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs index fb2b0f1a8ab6..05513d466eec 100644 --- a/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs +++ b/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs @@ -36,6 +36,8 @@ public class NavigationRenderer : UINavigationController, INavigationViewHandler bool _hasNavigationBar; UIImage _defaultNavBarShadowImage; UIImage _defaultNavBarBackImage; + Brush _currentBarBackgroundBrush; + Color _currentBarBackgroundColor; bool _disposed; IMauiContext _mauiContext; IMauiContext MauiContext => _mauiContext; @@ -257,6 +259,12 @@ protected override void Dispose(bool disposing) _secondaryToolbar.RemoveFromSuperview(); _secondaryToolbar.Dispose(); _secondaryToolbar = null; + + if(_currentBarBackgroundBrush is SolidColorBrush scb) + scb.InvalidateSolidColorBrushRequested -= OnBarBackgroundChanged; + + _currentBarBackgroundBrush = null; + _currentBarBackgroundColor = null; _parentFlyoutPage = null; Current = null; // unhooks events @@ -707,22 +715,42 @@ void UpdateBackgroundColor() View.BackgroundColor = color; } + void OnBarBackgroundChanged(object sender, EventArgs e) + { + RefreshBarBackground(); + } + void UpdateBarBackground() { - var barBackgroundColor = NavPage.BarBackgroundColor; - var barBackgroundBrush = NavPage.BarBackground; + if(_currentBarBackgroundBrush is SolidColorBrush oldSolidColorBrush) + { + oldSolidColorBrush.Parent = null; + oldSolidColorBrush.InvalidateSolidColorBrushRequested -= OnBarBackgroundChanged; + } + + _currentBarBackgroundColor = NavPage.BarBackgroundColor; + _currentBarBackgroundBrush = NavPage.BarBackground; // if the brush has a solid color, treat it as a Color so we can compute the alpha value - if (NavPage.BarBackground is SolidColorBrush scb) + if (_currentBarBackgroundBrush is SolidColorBrush newSolidColorBrush) { - barBackgroundColor = scb.Color; - barBackgroundBrush = null; + newSolidColorBrush.Parent = NavPage; + newSolidColorBrush.InvalidateSolidColorBrushRequested += OnBarBackgroundChanged; + _currentBarBackgroundColor = newSolidColorBrush.Color; } + RefreshBarBackground(); + } + + void RefreshBarBackground() + { + if (_currentBarBackgroundBrush is SolidColorBrush newSolidColorBrush) + _currentBarBackgroundColor = newSolidColorBrush.Color; + if (OperatingSystem.IsIOSVersionAtLeast(13) || OperatingSystem.IsMacCatalystVersionAtLeast(13)) { var navigationBarAppearance = NavigationBar.StandardAppearance; - if (barBackgroundColor is null) + if (_currentBarBackgroundColor is null) { navigationBarAppearance.ConfigureWithOpaqueBackground(); navigationBarAppearance.BackgroundColor = Maui.Platform.ColorExtensions.BackgroundColor; @@ -732,17 +760,17 @@ void UpdateBarBackground() } else { - if(barBackgroundColor?.Alpha < 1f) + if(_currentBarBackgroundColor?.Alpha < 1f) navigationBarAppearance.ConfigureWithTransparentBackground(); else navigationBarAppearance.ConfigureWithOpaqueBackground(); - navigationBarAppearance.BackgroundColor = barBackgroundColor.ToPlatform(); + navigationBarAppearance.BackgroundColor = _currentBarBackgroundColor.ToPlatform(); } - if (barBackgroundBrush is not null) + if (_currentBarBackgroundBrush is not null && _currentBarBackgroundBrush is not SolidColorBrush) { - var backgroundImage = NavigationBar.GetBackgroundImage(barBackgroundBrush); + var backgroundImage = NavigationBar.GetBackgroundImage(_currentBarBackgroundBrush); navigationBarAppearance.BackgroundImage = backgroundImage; } @@ -753,18 +781,18 @@ void UpdateBarBackground() } else { - if(barBackgroundColor?.Alpha == 0f) + if(_currentBarBackgroundColor?.Alpha == 0f) { NavigationBar.SetTransparentNavigationBar(); } else { // Set navigation bar background color - NavigationBar.BarTintColor = barBackgroundColor == null + NavigationBar.BarTintColor = _currentBarBackgroundColor == null ? UINavigationBar.Appearance.BarTintColor - : barBackgroundColor.ToPlatform(); + : _currentBarBackgroundColor.ToPlatform(); - var backgroundImage = NavigationBar.GetBackgroundImage(barBackgroundBrush); + var backgroundImage = NavigationBar.GetBackgroundImage(_currentBarBackgroundBrush); NavigationBar.SetBackgroundImage(backgroundImage, UIBarMetrics.Default); } } diff --git a/src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs b/src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs index 4720766995bc..6256b4d5b115 100644 --- a/src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs +++ b/src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs @@ -29,6 +29,8 @@ public class TabbedRenderer : UITabBarController, IPlatformViewHandler UITabBarAppearance _tabBarAppearance; WeakReference _element; + Brush _currentBarBackground; + IMauiContext MauiContext => _mauiContext; public static IPropertyMapper Mapper = new PropertyMapper(TabbedViewHandler.ViewMapper); public static CommandMapper CommandMapper = new CommandMapper(TabbedViewHandler.ViewCommandMapper); @@ -360,9 +362,26 @@ void UpdateBarBackground() if (Tabbed is not TabbedPage tabbed || TabBar == null) return; - var barBackground = tabbed.BarBackground; + if(_currentBarBackground is GradientBrush oldBarBackground) + { + oldBarBackground.Parent = null; + oldBarBackground.InvalidateGradientBrushRequested -= OnBarBackgroundChanged; + } + + _currentBarBackground = tabbed.BarBackground; - TabBar.UpdateBackground(barBackground); + if(_currentBarBackground is GradientBrush newGradientBrush) + { + newGradientBrush.Parent = tabbed; + newGradientBrush.InvalidateGradientBrushRequested += OnBarBackgroundChanged; + } + + TabBar.UpdateBackground(_currentBarBackground); + } + + void OnBarBackgroundChanged(object sender, EventArgs e) + { + TabBar.UpdateBackground(_currentBarBackground); } void UpdateBarTextColor() diff --git a/src/Controls/src/Core/Platform/Android/TabbedPageManager.cs b/src/Controls/src/Core/Platform/Android/TabbedPageManager.cs index 4fd95c9a6e81..584dcf8b7024 100644 --- a/src/Controls/src/Core/Platform/Android/TabbedPageManager.cs +++ b/src/Controls/src/Core/Platform/Android/TabbedPageManager.cs @@ -574,8 +574,30 @@ internal void UpdateBarBackground() if (_currentBarBackground == Element.BarBackground) return; + if(_currentBarBackground is GradientBrush oldGradientBrush) + { + oldGradientBrush.Parent = null; + oldGradientBrush.InvalidateGradientBrushRequested -= OnBarBackgroundChanged; + } + _currentBarBackground = Element.BarBackground; + if(_currentBarBackground is GradientBrush newGradientBrush) + { + newGradientBrush.Parent = Element; + newGradientBrush.InvalidateGradientBrushRequested += OnBarBackgroundChanged; + } + + RefreshBarBackground(); + } + + void OnBarBackgroundChanged(object sender, EventArgs e) + { + RefreshBarBackground(); + } + + void RefreshBarBackground() + { if (IsBottomTabPlacement) _bottomNavigationView.UpdateBackground(_currentBarBackground); else diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue24356.xaml b/src/Controls/tests/TestCases.HostApp/Issues/Issue24356.xaml new file mode 100644 index 000000000000..0a79389c32d2 --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue24356.xaml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue24356.xaml.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue24356.xaml.cs new file mode 100644 index 000000000000..9808f9db5bea --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue24356.xaml.cs @@ -0,0 +1,11 @@ +namespace Maui.Controls.Sample.Issues +{ + [Issue(IssueTracker.Github, 24356, "AppThemeBinding BarBackground with Brush in NavigationPage and TabbedPage not working", PlatformAffected.All)] + public partial class Issue24356 : TabbedPage + { + public Issue24356() + { + InitializeComponent(); + } + } +} diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue24356.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue24356.cs new file mode 100644 index 000000000000..11bd24338f75 --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue24356.cs @@ -0,0 +1,33 @@ +#if ANDROID || IOS +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues +{ + public class Issue24356 : _IssuesUITest + { + public Issue24356(TestDevice testDevice) : base(testDevice) + { + } + + public override string Issue => "AppThemeBinding BarBackground with Brush in NavigationPage and TabbedPage not working"; + + [Test] + [Category(UITestCategories.TabbedPage)] + public void GradientInTabBarShouldChange() + { + try { + App.WaitForElement("lightThemeLabel"); + App.SetDarkTheme(); + App.WaitForElement("darkThemeLabel"); + VerifyScreenshot(); + } + finally + { + App.SetLightTheme(); + } + } + } +} +#endif \ No newline at end of file