Skip to content

Commit

Permalink
fix(NavigationBar): Move to UINavigationAppearance APIs, fix unapplie…
Browse files Browse the repository at this point in the history
…d background color
  • Loading branch information
kazo0 committed Jan 26, 2022
1 parent 683d69f commit b43d371
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 40 deletions.
170 changes: 135 additions & 35 deletions src/Uno.UI/Controls/CommandBar/CommandBarRenderer.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Windows.UI.Xaml.Media;
using Uno.Extensions;
using Windows.UI;
using Foundation;

namespace Uno.UI.Controls
{
Expand Down Expand Up @@ -60,53 +61,111 @@ protected override IEnumerable<IDisposable> Initialize()
protected override void Render()
{
ApplyVisibility();

// Foreground
if (Brush.TryGetColorWithOpacity(Element.Foreground, out var foregroundColor))
{
Native.TitleTextAttributes = new UIStringAttributes
{
ForegroundColor = foregroundColor,
};
}
else
{
Native.TitleTextAttributes = null;
}

var appearance = new UINavigationBarAppearance();
// Background
var backgroundColor = Brush.GetColorWithOpacity(Element.Background);
switch (backgroundColor)
{
case { } opaqueColor when opaqueColor.A == byte.MaxValue:
// Prefer BarTintColor because it supports smooth transitions
Native.BarTintColor = opaqueColor;
Native.Translucent = false; //Make fully opaque for consistency with SetBackgroundImage
Native.SetBackgroundImage(null, UIBarMetrics.Default);
Native.ShadowImage = null;
if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
{

appearance.ConfigureWithOpaqueBackground();
appearance.BackgroundColor = opaqueColor;
}
else
{
// Prefer BarTintColor because it supports smooth transitions
Native.BarTintColor = opaqueColor;
Native.Translucent = false; //Make fully opaque for consistency with SetBackgroundImage
Native.SetBackgroundImage(null, UIBarMetrics.Default);
Native.ShadowImage = null;
}
break;
case { } semiTransparentColor when semiTransparentColor.A > 0:
Native.BarTintColor = null;
// Use SetBackgroundImage as hack to support semi-transparent background
Native.SetBackgroundImage(((UIColor)semiTransparentColor).ToUIImage(), UIBarMetrics.Default);
Native.Translucent = true;
Native.ShadowImage = null;
if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
{
appearance.ConfigureWithDefaultBackground();
appearance.BackgroundColor = semiTransparentColor;
}
else
{
Native.BarTintColor = null;
// Use SetBackgroundImage as hack to support semi-transparent background
Native.SetBackgroundImage(((UIColor)semiTransparentColor).ToUIImage(), UIBarMetrics.Default);
Native.Translucent = true;
Native.ShadowImage = null;
}
break;
case { } transparent when transparent.A == 0:
Native.BarTintColor = null;
Native.SetBackgroundImage(new UIImage(), UIBarMetrics.Default);
// We make sure a transparent bar doesn't cast a shadow.
Native.ShadowImage = new UIImage(); // Removes the default 1px line
Native.Translucent = true;
if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
{
appearance.ConfigureWithTransparentBackground();
appearance.BackgroundColor = transparent;
}
else
{
Native.BarTintColor = null;
Native.SetBackgroundImage(new UIImage(), UIBarMetrics.Default);
// We make sure a transparent bar doesn't cast a shadow.
Native.ShadowImage = new UIImage(); // Removes the default 1px line
Native.Translucent = true;
}
break;
default: //Background is null
Native.BarTintColor = null;
Native.SetBackgroundImage(null, UIBarMetrics.Default); // Restores the default blurry background
Native.ShadowImage = null; // Restores the default 1px line
Native.Translucent = true;
if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
{
appearance.ConfigureWithDefaultBackground();
appearance.BackgroundColor = null;

}
else
{
Native.BarTintColor = null;
Native.SetBackgroundImage(null, UIBarMetrics.Default); // Restores the default blurry background
Native.ShadowImage = null; // Restores the default 1px line
Native.Translucent = true;
}
break;
}

// Foreground
if (Brush.TryGetColorWithOpacity(Element.Foreground, out var foregroundColor))
{
if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
{
appearance.TitleTextAttributes = new UIStringAttributes
{
ForegroundColor = foregroundColor,
};

appearance.LargeTitleTextAttributes = new UIStringAttributes
{
ForegroundColor = foregroundColor,
};
}
else
{
Native.TitleTextAttributes = new UIStringAttributes
{
ForegroundColor = foregroundColor,
};
}
}
else
{
if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
{
appearance.TitleTextAttributes = new UIStringAttributes();
appearance.LargeTitleTextAttributes = new UIStringAttributes();
}
else
{
Native.TitleTextAttributes = null;
}

}

// CommandBarExtensions.BackButtonForeground
var backButtonForeground = Brush.GetColorWithOpacity(Element.GetValue(BackButtonForegroundProperty) as Brush);
Native.TintColor = backButtonForeground;
Expand All @@ -116,8 +175,49 @@ protected override void Render()
? UIImageHelper.FromUri(bitmapIcon.UriSource)?.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
: null;

Native.BackIndicatorImage = backButtonIcon;
Native.BackIndicatorTransitionMaskImage = backButtonIcon;
if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
{
var backButtonAppearance = new UIBarButtonItemAppearance(UIBarButtonItemStyle.Plain);

if (backButtonForeground is { } foreground)
{
var titleTextAttributes = new UIStringAttributes
{
ForegroundColor = foreground
};

var attributes = new NSDictionary<NSString, NSObject>(
new NSString[] { titleTextAttributes.Dictionary.Keys[0] as NSString }, titleTextAttributes.Dictionary.Values
);

backButtonAppearance.Normal.TitleTextAttributes = attributes;
backButtonAppearance.Highlighted.TitleTextAttributes = attributes;

if (backButtonIcon is { } image)
{
var tintedImage = image.ApplyTintColor(foreground);
appearance.SetBackIndicatorImage(tintedImage, tintedImage);
}
}
else
{
if (backButtonIcon is { } image)
{
appearance.SetBackIndicatorImage(image, image);
}
}

appearance.BackButtonAppearance = backButtonAppearance;
}
else
{
Native.BackIndicatorImage = backButtonIcon;
Native.BackIndicatorTransitionMaskImage = backButtonIcon;
}

Native.CompactAppearance = appearance;
Native.StandardAppearance = appearance;
Native.ScrollEdgeAppearance = appearance;
}

private void ApplyVisibility()
Expand Down
13 changes: 8 additions & 5 deletions src/Uno.UI/UI/Xaml/Style/Generic/Generic.Native.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
xmlns:macos="http://uno.ui/macos"
xmlns:net461="http://uno.ui/net461"
xmlns:not_wasm="http://uno.ui/not_wasm"
xmlns:toolkit="using:Uno.UI.Toolkit"
mc:Ignorable="d xamarin ios android skia wasm not_wasm net461 macos">

<!-- Default native Button styles -->
Expand Down Expand Up @@ -401,23 +402,23 @@
BasedOn="{StaticResource XamlDefaultPivot}" />

<ios:Style x:Key="NativeDefaultCommandBar"
TargetType="CommandBar">
TargetType="CommandBar">
<Setter Property="Background"
Value="{x:Null}" />
<Setter Property="Foreground"
Value="{x:Null}" />
<Setter Property="uBehaviors:InternalVisibleBoundsPadding.PaddingMask"
Value="Top" />
<Setter Property="HorizontalAlignment"
Value="Stretch" />
<Setter Property="VerticalAlignment"
Value="Top" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CommandBar">
<!-- We use BorderBrush instead of Background to ensure that semi-transparent background of Grid and NativeCommandBarPresenter don't add up -->
<Border BorderBrush="{TemplateBinding Background}"
BorderThickness="{TemplateBinding Padding}">
<Border BorderThickness="{TemplateBinding Padding}">
<!-- TODO: 1px line -->
<NativeCommandBarPresenter />
<NativeCommandBarPresenter Height="44" />
</Border>
</ControlTemplate>
</Setter.Value>
Expand All @@ -430,6 +431,8 @@
Value="{x:Null}" />
<Setter Property="Foreground"
Value="{x:Null}" />
<Setter Property="uBehaviors:InternalVisibleBoundsPadding.PaddingMask"
Value="Top" />
<Setter Property="HorizontalAlignment"
Value="Stretch" />
<Setter Property="VerticalAlignment"
Expand Down

0 comments on commit b43d371

Please sign in to comment.