Hello,
I work on a Xamarin.Forms app where I need to implement transparent/translucent navigation bar.
I've studied the the Vision Conference sample, where this is implemented.
This is achieved through a CustomNavigationPage
and a CustomRenderer
.
The XAML of the CustomNavigationPage
is:
<?xml version="1.0" encoding="utf-8" ?>
<NavigationPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ConferenceVision.Views.CustomNavigationPage"
xmlns:iOS="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
iOS:NavigationPage.IsNavigationBarTranslucent="True"
BarTextColor="{StaticResource NavigationBarTextColor}">
<NavigationPage.BarBackgroundColor>
<OnPlatform x:TypeArguments="Color">
<On Platform="Android, iOS" Value="Transparent" />
<On Platform="UWP" Value="{StaticResource NavigationBarBackgroundColor}" />
</OnPlatform>
</NavigationPage.BarBackgroundColor>
</NavigationPage>
The code-behind of the CustomNavigationPage
is:
public partial class CustomNavigationPage : NavigationPage
{
public bool IgnoreLayoutChange { get; set; } = false;
protected override void OnSizeAllocated(double width, double height)
{
if (!IgnoreLayoutChange)
base.OnSizeAllocated(width, height);
}
public CustomNavigationPage() : base()
{
InitializeComponent();
}
public CustomNavigationPage(Page root) : base(root)
{
InitializeComponent();
}
}
And the CustomRenderer
is:
public class CustomNavigationRenderer : NavigationRenderer
{
public override void ViewDidLoad()
{
base.ViewDidLoad();
UINavigationBar.Appearance.SetBackgroundImage(new UIImage(), UIBarMetrics.Default);
UINavigationBar.Appearance.ShadowImage = new UIImage();
UINavigationBar.Appearance.BackgroundColor = UIColor.Clear;
UINavigationBar.Appearance.TintColor = UIColor.White;
UINavigationBar.Appearance.BarTintColor = UIColor.Clear;
UINavigationBar.Appearance.Translucent = true;
UINavigationBar.Appearance.SetTitleTextAttributes(new UITextAttributes()
{
Font = UIFont.FromName("HelveticaNeue-Light", (nfloat)20f),
TextColor = UIColor.White
});
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
}
base.Dispose(disposing);
}
}
I've tested the app on :
- simulators : iPhone 6 on iOS 11.3
- my device : iPhone 6 on iOS 10.1
And we can see that the results are not the same. On the simulator and iOS 11.3, there is a gap between the navigation bar and the content:
But on my device under iOS 10.1, there is no gap and the content is displayed "under" the navigation bar:
The page is built like that, but the rendering is the same on all pages:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:effects="clr-namespace:ConferenceVision.Effects"
xmlns:local="clr-namespace:ConferenceVision.Views.Renderers"
xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
ios:Page.UseSafeArea="true"
Title="About"
x:Class="ConferenceVision.Views.AboutView">
<ContentPage.Content>
<ScrollView>
<ScrollView.Margin>
<OnPlatform x:TypeArguments="Thickness" Default="15,0">
<On Platform="Android" Value="15,50,15,0"/>
</OnPlatform>
</ScrollView.Margin>
...
</ScrollView>
</ContentPage.Content>
</ContentPage>
How explain it? Could this be related to the use of UseSafeArea
?
I know that I get an "old" version on my device, but in my app I have to cover the largest number of users.