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 :
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.
Posts
When you set the
UINavigationBar
'sTranslucent
to true, the controller's content will be rendered from the point (0, 0) instead of (0, navigationBar's height). So your content looks covered by navigation bar. But iOS offers us a property calledAutomaticallyAdjustsScrollViewInsets
, when it is set to true the view controller will automatically adjust its view insets. On iOS 11 because of safe area apple deprecate this api and recommend developers to use 'UIScrollView.ContentInsetAdjustmentBehavior' instead. It seems Forms doesn't supportAutomaticallyAdjustsScrollViewInsets
very well, but works properly on iOS 11.I think we can achieve this effect manually like:
Create a custom renderer for your issue page, put the code above there.
@LandLu Thank you for the answer.
Is there any update to this solution? Can we get this working without implementing a CustomRender?
Please let us know, we are also facing the same issue right now and we need to support our app from iOS 9 onwards.