xamarin / Xamarin.Forms

Xamarin.Forms is no longer supported. Migrate your apps to .NET MAUI.
https://aka.ms/xamarin-upgrade
Other
5.62k stars 1.87k forks source link

[Bug] iOS Translucent no longer works with UIAppearance #11138

Open davidortinau opened 4 years ago

davidortinau commented 4 years ago

Description

When setting the NavBar translucent, and setting the UIAppearance to make it clear, the bar used to be completely transparent. Now it isn't.

The bar was transparent in 4.3, but it is no longer in 4.6 or 4.7 (from my tests).

Here is a series of images from different versions, no negative margins to pull the content (ListView) under the bar tho. The changes to the nav bar appearance are obvious...not sure what has been doing on, but things are changing that much is clear (pun intended).

4.3.0

4 3 0

4.4.0

4 4 0

4.5.0

4 5 0

4.7.0

4 7 0

Here are images showing the the bar is transparent under 4.3 and not under 4.7.

4.3.0 Grid with negative margin

4 3 0-Grid-NegMargin

4.7.0 Grid with negative margin

4 7 0-Grid-NegMargin
<?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:d="http://xamarin.com/schemas/2014/forms/design"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
    ios:NavigationPage.IsNavigationBarTranslucent="True"
    ios:Page.UseSafeArea="True"
    mc:Ignorable="d"
    x:Class="repro.Views.TranslucentNavbarWithTableViewAndRefreshView"
    Title="{Binding Title}"
    x:Name="BrowseItemsPage">

    <ContentPage.ToolbarItems>
        <ToolbarItem
            Text="Add"
            Clicked="AddItem_Clicked" />
    </ContentPage.ToolbarItems>

    <ListView
            Margin="0,-56"
            ItemsSource="{Binding Items}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextCell
                        Text="{Binding Text}"
                        Detail="{Binding Description}" />
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

</ContentPage>

CustomNavigationRenderer:

[assembly: ExportRenderer(typeof(NavigationPage), typeof(CustomNavigationRenderer))]
namespace repro.iOS.Renderers
{
    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.Translucent = true;
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
            }

            base.Dispose(disposing);
        }
    }
}

Expected Behavior

If just setting the iOS translucent property, the bar should be partially transparent and scrollable content should appear behind it.

Setting customer UIAppearance so the bar is completely transparent should still work, or some other method to achieve this should be made available in Forms (#1698).

Basic Information

Reproduction Link

repro_4.7.0.zip

pwillies commented 4 years ago

@pauldipietro @samhouts Hi XF Team, This is on our priority list. Not quite critical because it is cosmetic. But it used to work on our previous version, and now it no longer works. So seems like an obvious backwards step in the app.

rachelkang commented 3 years ago

@davidortinau @pwillies thanks for bringing this to our attention! So there's a few different things going on here and I've spent the past week with the help of @rmarinho getting to the bottom of this :)

NavBar Changes introduced in iOS 13 Firstly, your code works as you expect it to on versions of iOS under iOS13! There were a number of NavBar changes introduced in iOS13 which makes the implementation a bit different and which is why your NavBar doesn't appear transparent on iOS13+. So, we need to add a bit more code, the key piece being navigationBarAppearance.ConfigureWithTransparentBackground();, to your custom renderer:

[assembly: ExportRenderer(typeof(Issue11138NavigationPage), typeof(_11138CustomRenderer))]
namespace Xamarin.Forms.ControlGallery.iOS.CustomRenderers
{
    public class _11138CustomRenderer : 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.Translucent = true;

            if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
            {
                var navigationBarAppearance = NavigationBar.StandardAppearance;
                navigationBarAppearance.ConfigureWithTransparentBackground();
                SetAppearanceOnNavigationBar(navigationBarAppearance);
            }
        }

        void SetAppearanceOnNavigationBar(UINavigationBarAppearance navigationBarAppearance)
        {
            NavigationBar.CompactAppearance = navigationBarAppearance;
            NavigationBar.StandardAppearance = navigationBarAppearance;
            NavigationBar.ScrollEdgeAppearance = navigationBarAppearance;
        }
    }
}

Transparent vs. Translucent It seems that what you're trying to achieve here is a transparent NavBar - one that is completely clear and see-through such that you can see the text through it. You achieve this via your custom renderer. Although transparency and translucency are very similar and related, they are not the same.

Therefore, the IsNavigationBarTranslucent property you set ios:NavigationPage.IsNavigationBarTranslucent="True" is actually not at all needed here. The transparency you set is dictated by your custom renderer - not by this property which behaves differently. More on NavBar translucency here!

Another thing to note is that when the IsNavigationBarTranslucent property is set, it should be set on the NavigationPage (not the ContentPage), which you can also see in the docs linked above.

Hope all this helps!!! Let me know if you have any questions, or if you think I might be misunderstanding something. I'm also continuing to explore some of the nuances of translucency, especially with the changes that were introduced in iOS13.

LittleCornerDev commented 3 years ago

Hi! I also have an issue where nav bar transparency does not work for iOS (but works in Android). My usage is slightly different as the custom NavigationPage is created via CS (not XAML) because it is dynamically created as a TabbedPage child. The updated renderer code that checks for iOS13+ helpfully provided by @rachelkang above doesn't work in my case.

In case it helps, I have the following version info: Physical Device Software: iOS 14.2 Physical Device Model: iPhone 7 Plus Visual Studio Community 2019 for Mac Version 8.8.4 (build 30) Xamarin.Forms Version: 4.8.0.1821 Apple Developer Tools: Xcode 12.3 (17715) Xamarin.Mac Version: 7.0.0.15 (Visual Studio Community) Xamarin.iOS Version: 14.6.0.15 (Visual Studio Community)

The custom NavigationPage instance that needs transparency has BarBackgroundColor = Color.Transparent; set. I check for this condition in the custom renderer before setting any of the transparency properties because not all the navigation pages created by the tabs need nav bar transparency.

Since the navigation pages are created via CS, I do not have ios:NavigationPage.IsNavigationBarTranslucent="True" in an XAML, but I do have On<iOS>().EnableTranslucentNavigationBar(); on the CS as per this documentation. The aforementioned post by @rachelkang above mentioned it as possibly unnecessary, but taking it out does not seem to make a difference. The nav bar background remains solid white in light mode or solid black in dark mode.

Is there something else I'm missing? My original custom renderer is pretty much the same as what @davidortinau originally posted and was based on this post from 2018.

Any tips/pointers would be appreciated!

pboisso commented 3 years ago

Following this thread as well.