Xamarin.forms: [Bug][iOS] NavigationPage.HideNavigationBarSeparator="true" doesn't work from XAML

Created on 5 May 2020  路  8Comments  路  Source: xamarin/Xamarin.Forms

Description

On previous versions of iOS it was possible to hide the navigation bar separator, using XAML, with the NavigationPage.HideNavigationBarSeparator platform-specific. However, this doesn't work on iOS 13.4.

This issue was previously reported in #10438 and found not to be a problem. After further investigation I can be more precise about the exact issue:

  1. The platform-specific doesn't work at all from XAML (I've tried setting NavigationPage.HideNavigationBarSeparator="true" on both a NavigationPage instance and a ContentPage instance. Neither results in the separator being hidden.
  2. The platform-specific works from C#, provided that it's not also been set from XAML. When it has been set in XAML, it can be coaxed back into life from C# with specific repro steps (see below).

Steps to Reproduce

  1. Run the attached sample on iOS 13.4.

Expected Behavior

Navigation bar separator is hidden by default, and the hide/show buttons work.

Actual Behavior

The sample as provided:

  • Navigation bar separator is shown.
  • Hide button has no effect. However, pressing the Show button (which produces no visual change) then the Hide button results in the navigation bar separator being hidden.

The sample when ios:NavigationPage.HideNavigationBarSeparator="True" is removed from MyNavigationPage.xaml:

  • Navigation bar separator hides/shows as expected (from C#).

Basic Information

  • Version with issue: 4.6.0.726
  • IDE: VSMac 8.5.4
  • Platform Target Frameworks:

    • iOS: 13.4

Reproduction Link

test.zip

Workaround

This platform-specific works fine from C#, provided that it's not set from XAML first.

Xaml </> navbar blocker high impact iOS 馃崕 bug

All 8 comments

Hello! Thank you for repro!

I honestly don't understand how this works.

Using version 4.6.0.726 of Xamarin.Forms, I'm using Tabbed Page.

I cannot use .MainPage in TabbedPage so I created subclass of NavigationPage:

  public class NoBarSeparatorNavigationPage : Xamarin.Forms.NavigationPage {
    public NoBarSeparatorNavigationPage(Xamarin.Forms.Page page) : base(page) {
    }

    protected override void OnAppearing() {
      Debug.WriteLine("Hiding navigation bar");
      On<iOS>().SetHideNavigationBarSeparator(true);
      base.OnAppearing();
    }
  }

I use it in MainPage.xaml file instead of to store pages inside Tabbed Page

I'm using OnAppearing because constructor call to hide separator does not even work.

Fortunately it hides separator, BUT makes background of navigation bar somewhat... grayish?
Edit: this is not because of this. I think it's because I'm using my custom class, it makes it grayish for some reason. Fixed by manually making BackgroundColor = Color.White in constructor

P.S. It does not hide separator for long 馃槩
It would reappear again when switching tabs in Tabbed Page layout.

懈蟹芯斜褉邪卸械薪懈械

I hope this may be of help:

No code like:

var bar = NavigationBar;


bar.StandardAppearance.ShadowColor = UIColor.Clear;
bar.StandardAppearance.ShadowImage = new UIImage();

works in ViewDidLoad in custom renderer for NavigationPage, when used in Tabbed Page.

BUT

it works flawlessly in ViewWillAppear method

I am having an identical issue here as well. The only persistent resolution for me was the custom renderer.

@AaronBastian please share your solution, because my tries with custom renderer were unhelpful, since when I changed translucent or background color - separator returned by some code inside Xamarin Forms

@idchlife my solution was as follows:

`
public override void ViewDidLoad()
{
base.ViewDidLoad();
UINavigationBar.Appearance.TintColor = UIColor.White;
}

    public override void ViewWillAppear(bool animated)
    {
        base.ViewWillAppear(animated);
        var bar = NavigationBar;
        bar.StandardAppearance.ShadowColor = UIColor.Clear;
        bar.StandardAppearance.ShadowImage = new UIImage();
    }

`
I did NOT keep my changes to the XAML because they were completely ineffective. The renderer was my only solution.

Hey,
I used this temporary fix for 4.5.356 and newer (for those, who found this issue and cannot solve it). It isn't best way to do it, but works.

[assembly: ExportRenderer(typeof(**NavigationPage/CustomNavigationPage**), typeof(NoLineNavigationPageRenderer))]
namespace MyLibrary.iOS.Renderers
{
    public class NoLineNavigationPageRenderer : NavigationRenderer
    {

        public override void ViewWillAppear(bool animated)
        {
            base.ViewWillAppear(animated);

            if (Element is Xamarin.Forms.NavigationPage navigationPage)
            {
                //iOS older version fix
                NavigationBar.SetBackgroundImage(new UIKit.UIImage(), UIKit.UIBarMetrics.Default);
                NavigationBar.ShadowImage = new UIKit.UIImage();
                NavigationBar.ClipsToBounds = true;
                try //Newest iOS version fix - trycatch isn't optimal
                {
                    NavigationBar.ScrollEdgeAppearance.ShadowImage = new UIKit.UIImage();
                    NavigationBar.ScrollEdgeAppearance.ShadowColor = null;
                }
                catch (Exception) { }
            }
        }
    }
}

@davidbritch Did it ever work on a ContentPage instance?

I can't see code in the current NavigationRenderer that makes me believe otherwise.

@pauldipietro @jsuarezruiz @samhouts @StephaneDelcroix @davidbritch Hi XF Team, This is on our priority list. Also something visual, but it's a regression that can be seen on most views in our app.

Was this page helpful?
0 / 5 - 0 ratings