Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

[iOS] Fix Shell NavigationBar and TabBar color issues #14649

Merged
merged 9 commits into from
Oct 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;

#if UITEST
using Xamarin.Forms.Core.UITests;
using NUnit.Framework;
using Xamarin.UITest;
#endif

namespace Xamarin.Forms.Controls.Issues
{
[Preserve(AllMembers = true)]
[Issue(IssueTracker.None, 0, "TabbedPage BarBackgroundColor not working on iOS 15", PlatformAffected.iOS)]
public class Issue14505_II : TestTabbedPage
{
public Issue14505_II()
{
BarBackgroundColor = Color.Red;
BarTextColor = Color.White;
SelectedTabColor = Color.Green;
UnselectedTabColor = Color.Blue;
}

protected override void Init()
{
Children.Add(new ContentPage() { Title = "Tab 1", Content = CreateTabContent() });
Children.Add(new ContentPage() { Title = "Tab 2", Content = CreateTabContent() });
}

Grid CreateTabContent()
{
var layout = new Grid
{
Margin = 12
};

var instructions = new Label
{
BackgroundColor = Color.Black,
TextColor = Color.White,
Text = "If TabBar BarBackgroundColor is Red, the test has passed."
};

layout.Children.Add(instructions);

return layout;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;

#if UITEST
using Xamarin.UITest;
using NUnit.Framework;
using Xamarin.Forms.Core.UITests;
#endif

namespace Xamarin.Forms.Controls.Issues
{
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 14505, "[Bug] Shell BackgroundColor and TabBarBackgroundColor do not update on iOS 15", PlatformAffected.iOS)]
#if UITEST
[NUnit.Framework.Category(UITestCategories.Shell)]
#endif
public class Issue14505 : TestShell
{
const string Test1 = "Test 1";
const string Test2 = "Test 2";

protected override void Init()
{
AddBottomTab(CreatePage1(Test1), Test1);
AddBottomTab(CreatePage2(Test2), Test2);

static ContentPage CreatePage1(string title)
{
var layout = new StackLayout();

var instructions = new Label
{
Padding = 12,
BackgroundColor = Color.Black,
TextColor = Color.White,
Text = "If the NavigationBar is Red, everything is ok. Pass to the next Tab."
};

layout.Children.Add(instructions);

var contentPage1 = new ContentPage
{
Title = title,
Content = layout
};

Shell.SetBackgroundColor(contentPage1, Color.Red);
Shell.SetForegroundColor(contentPage1, Color.Yellow);
Shell.SetTabBarBackgroundColor(contentPage1, Color.Red);
Shell.SetTabBarForegroundColor(contentPage1, Color.Yellow);

return contentPage1;
}

static ContentPage CreatePage2(string title)
{
var layout = new StackLayout();

var instructions = new Label
{
Padding = 12,
BackgroundColor = Color.Black,
TextColor = Color.White,
Text = "If the NavigationBar is Green, the test has passed."
};

layout.Children.Add(instructions);

var contentPage2 = new ContentPage
{
Title = title,
Content = layout
};

Shell.SetBackgroundColor(contentPage2, Color.Green);
Shell.SetForegroundColor(contentPage2, Color.Red);
Shell.SetTabBarBackgroundColor(contentPage2, Color.Green);
Shell.SetTabBarForegroundColor(contentPage2, Color.Red);

return contentPage2;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,23 @@
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:local="clr-namespace:Xamarin.Forms.Controls.Issues"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
mc:Ignorable="d"
BackgroundColor="Purple"
ForegroundColor="White"
TitleColor="White"
DisabledColor="LightGray"
UnselectedColor="Gray">
<ShellItem>
<ShellSection Title="Issue 1" IsEnabled="False">
<ShellContent>
<ShellSection Icon="coffee.png" Title="Issue 1" IsEnabled="False">
<ShellContent
Shell.TabBarBackgroundColor="Red"
Shell.TabBarTitleColor="Yellow"
Shell.TabBarUnselectedColor="Green"
Shell.TabBarDisabledColor="Purple">
<local:PageInstruction PageNumber="1" />
</ShellContent>
</ShellSection>
<ShellSection Title="Issue 2" IsEnabled="False">
<ShellSection Icon="coffee.png" Title="Issue 2" IsEnabled="False">
<ShellContent>
<local:PageInstruction PageNumber="2" />
</ShellContent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1782,6 +1782,8 @@
<Compile Include="$(MSBuildThisFileDirectory)Issue13818.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)FrameBackgroundIssue.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue14192.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue14505.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue14505-II.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Bugzilla22229.xaml">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,8 @@ public virtual void ResetAppearance(UITabBarController controller)

public virtual void SetAppearance(UITabBarController controller, ShellAppearance appearance)
{
IShellAppearanceElement appearanceElement = appearance;
var backgroundColor = appearanceElement.EffectiveTabBarBackgroundColor;
var foregroundColor = appearanceElement.EffectiveTabBarForegroundColor; // currently unused
var disabledColor = appearanceElement.EffectiveTabBarDisabledColor; // unused on iOS
var unselectedColor = appearanceElement.EffectiveTabBarUnselectedColor;
var titleColor = appearanceElement.EffectiveTabBarTitleColor;

var tabBar = controller.TabBar;

bool operatingSystemSupportsUnselectedTint = Forms.IsiOS10OrNewer;

if (_defaultTint == null)
Expand All @@ -44,23 +38,86 @@ public virtual void SetAppearance(UITabBarController controller, ShellAppearance
}
}

if (Forms.IsiOS15OrNewer)
UpdateiOS15TabBarAppearance(controller, appearance);
else
UpdateTabBarAppearance(controller, appearance);
}

public virtual void UpdateLayout(UITabBarController controller)
{
}

void UpdateiOS15TabBarAppearance(UITabBarController controller, ShellAppearance appearance)
{
IShellAppearanceElement appearanceElement = appearance;

var tabBar = controller.TabBar;

var tabBarAppearance = new UITabBarAppearance();
tabBarAppearance.ConfigureWithOpaqueBackground();

// Set TabBarBackgroundColor
var tabBarBackgroundColor = appearanceElement.EffectiveTabBarBackgroundColor;

if (!tabBarBackgroundColor.IsDefault)
tabBarAppearance.BackgroundColor = tabBarBackgroundColor.ToUIColor();

// Set TabBarTitleColor
var tabBarTitleColor = appearanceElement.EffectiveTabBarTitleColor;

if (!tabBarTitleColor.IsDefault)
{
tabBarAppearance.StackedLayoutAppearance.Normal.TitleTextAttributes = tabBarAppearance.StackedLayoutAppearance.Selected.TitleTextAttributes = new UIStringAttributes { ForegroundColor = tabBarTitleColor.ToUIColor() };
tabBarAppearance.StackedLayoutAppearance.Normal.IconColor = tabBarAppearance.StackedLayoutAppearance.Selected.IconColor = tabBarTitleColor.ToUIColor();
}

//Set TabBarUnselectedColor
var tabBarUnselectedColor = appearanceElement.EffectiveTabBarUnselectedColor;

if (!tabBarUnselectedColor.IsDefault)
{
tabBarAppearance.StackedLayoutAppearance.Normal.TitleTextAttributes = new UIStringAttributes { ForegroundColor = tabBarUnselectedColor.ToUIColor() };
tabBarAppearance.StackedLayoutAppearance.Normal.IconColor = tabBarUnselectedColor.ToUIColor();
}

// Set TabBarDisabledColor
var tabBarDisabledColor = appearanceElement.EffectiveTabBarDisabledColor;

if (!tabBarDisabledColor.IsDefault)
{
tabBarAppearance.StackedLayoutAppearance.Disabled.TitleTextAttributes = new UIStringAttributes { ForegroundColor = tabBarDisabledColor.ToUIColor() };
tabBarAppearance.StackedLayoutAppearance.Disabled.IconColor = tabBarDisabledColor.ToUIColor();
}

tabBar.StandardAppearance = tabBar.ScrollEdgeAppearance = tabBarAppearance;
}

void UpdateTabBarAppearance(UITabBarController controller, ShellAppearance appearance)
{
IShellAppearanceElement appearanceElement = appearance;
var backgroundColor = appearanceElement.EffectiveTabBarBackgroundColor;
var unselectedColor = appearanceElement.EffectiveTabBarUnselectedColor;
var titleColor = appearanceElement.EffectiveTabBarTitleColor;

var tabBar = controller.TabBar;

if (!backgroundColor.IsDefault)
tabBar.BarTintColor = backgroundColor.ToUIColor();
if (!titleColor.IsDefault)
tabBar.TintColor = titleColor.ToUIColor();

bool operatingSystemSupportsUnselectedTint = Forms.IsiOS10OrNewer;

if (operatingSystemSupportsUnselectedTint)
{
if (!unselectedColor.IsDefault)
tabBar.UnselectedItemTintColor = unselectedColor.ToUIColor();
}
}

public virtual void UpdateLayout(UITabBarController controller)
{
}

#region IDisposable Support

protected virtual void Dispose(bool disposing)
{
}
Expand All @@ -69,7 +126,7 @@ public void Dispose()
{
Dispose(true);
}
#endregion

#endregion
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
using System.ComponentModel;
using CoreGraphics;
using CoreGraphics;
using UIKit;

namespace Xamarin.Forms.Platform.iOS
Expand All @@ -22,17 +20,14 @@ public void ResetAppearance(UINavigationController controller)
if (_defaultTint != null)
{
var navBar = controller.NavigationBar;
navBar.BarTintColor = _defaultBarTint;
navBar.TintColor = _defaultTint;
navBar.TitleTextAttributes = _defaultTitleAttributes;
}
}

public void SetAppearance(UINavigationController controller, ShellAppearance appearance)
{
var background = appearance.BackgroundColor;
var foreground = appearance.ForegroundColor;
var titleColor = appearance.TitleColor;

var navBar = controller.NavigationBar;

if (_defaultTint == null)
Expand All @@ -41,6 +36,20 @@ public void SetAppearance(UINavigationController controller, ShellAppearance app
_defaultTint = navBar.TintColor;
_defaultTitleAttributes = navBar.TitleTextAttributes;
}

if (Forms.IsiOS15OrNewer)
UpdateiOS15NavigationBarAppearance(controller, appearance);
else
UpdateNavigationBarAppearance(controller, appearance);
}

void UpdateNavigationBarAppearance(UINavigationController controller, ShellAppearance appearance)
{
var background = appearance.BackgroundColor;
var foreground = appearance.ForegroundColor;
var titleColor = appearance.TitleColor;

var navBar = controller.NavigationBar;

if (!background.IsDefault)
navBar.BarTintColor = background.ToUIColor();
Expand All @@ -55,14 +64,34 @@ public void SetAppearance(UINavigationController controller, ShellAppearance app
}
}

#region IDisposable Support
protected virtual void Dispose(bool disposing)
void UpdateiOS15NavigationBarAppearance(UINavigationController controller, ShellAppearance appearance)
{
}
var navBar = controller.NavigationBar;

public void Dispose()
{
Dispose(true);
var navigationBarAppearance = new UINavigationBarAppearance();
navigationBarAppearance.ConfigureWithOpaqueBackground();

navBar.Translucent = false;
Copy link
Member

Choose a reason for hiding this comment

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

In line with the one for tab bar... Not sure about this one?


// Set ForegroundColor
var foreground = appearance.ForegroundColor;

if (!foreground.IsDefault)
navBar.TintColor = foreground.ToUIColor();

// Set BackgroundColor
var background = appearance.BackgroundColor;

if (!background.IsDefault)
navigationBarAppearance.BackgroundColor = background.ToUIColor();

// Set TitleColor
var titleColor = appearance.TitleColor;

if (!titleColor.IsDefault)
navigationBarAppearance.TitleTextAttributes = new UIStringAttributes() { ForegroundColor = titleColor.ToUIColor() };

navBar.StandardAppearance = navBar.ScrollEdgeAppearance = navigationBarAppearance;
}

public virtual void SetHasShadow(UINavigationController controller, bool hasShadow)
Expand All @@ -89,6 +118,18 @@ public virtual void SetHasShadow(UINavigationController controller, bool hasShad
navigationBar.Layer.ShadowOpacity = _shadowOpacity;
}
}

#region IDisposable Support

protected virtual void Dispose(bool disposing)
{
}

public void Dispose()
{
Dispose(true);
}

#endregion
}
}
Loading