DEV Community

Cover image for Remove iOS Navigation Bar Separator in .NET MAUI
Victor Hugo Garcia
Victor Hugo Garcia

Posted on

Remove iOS Navigation Bar Separator in .NET MAUI

If you are developing a .NET MAUI app for iOS you may need to update the UI of the Navigation Bar when using Shell. In this post, I will show you how to remove the navigation bar separator for iOS using a simple custom handler and some native code. Let’s get started!


Create a custom handler class

Create the following class under the /Platforms/iOS folder

using System;
using Microsoft.Maui.Controls.Handlers.Compatibility;
using Microsoft.Maui.Controls.Platform.Compatibility;
using UIKit;

namespace Test.Platforms.iOS
{
    public class CustomAppShell : ShellRenderer
    {
        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
        }
        protected override IShellTabBarAppearanceTracker CreateTabBarAppearanceTracker()
        {
            return new MyBottomNavViewAppearanceTracker();
        }
        protected override IShellNavBarAppearanceTracker CreateNavBarAppearanceTracker()
        {
            return new NoLineAppearanceTracker();
        }
    }
    public class NoLineAppearanceTracker : IShellNavBarAppearanceTracker
    {
        public void Dispose()
        {
        }
        public void ResetAppearance(UINavigationController controller)
        {
        }
        public void SetAppearance(UINavigationController controller, ShellAppearance appearance)
        {
            var navBar = controller.NavigationBar;
            var navigationBarAppearance = new UINavigationBarAppearance();
            navigationBarAppearance.ConfigureWithTransparentBackground();
            navigationBarAppearance.ShadowColor = UIColor.Clear;
            navigationBarAppearance.BackgroundColor = UIColor.Clear;
            navigationBarAppearance.BackgroundEffect = null;
            navBar.ScrollEdgeAppearance = navBar.StandardAppearance = navigationBarAppearance;
        }
        public void SetHasShadow(UINavigationController controller, bool hasShadow)
        {
        }
        public void UpdateLayout(UINavigationController controller)
        {
        }
    }
    class MyBottomNavViewAppearanceTracker : IShellTabBarAppearanceTracker
    {
        public void Dispose()
        {

        }
        public void ResetAppearance(UITabBarController controller)
        {

        }
        public void SetAppearance(UITabBarController controller, ShellAppearance appearance)
        {
            var topBar = controller.TabBar;
            var topBarAppearance = new UITabBarAppearance();
            topBarAppearance.ConfigureWithTransparentBackground();
            topBarAppearance.ShadowColor = UIColor.Clear;
            topBarAppearance.BackgroundColor = UIColor.Clear;
            topBarAppearance.BackgroundEffect = null;
            topBar.ScrollEdgeAppearance = topBar.StandardAppearance = topBarAppearance;
        }
        public void UpdateLayout(UITabBarController controller)
        {

        }
    }
}
Enter fullscreen mode Exit fullscreen mode

On the code shared above, in addition to remove the navigation bar separator, I set the background color of the top bar appearance to be transparent by using UIColor.Clear, feel free to update it as needed for your requirements.

Register the handler

On the MauiProgram.cs file register the handler

.ConfigureMauiHandlers(handlers =>
            {
#if IOS
                handlers.AddHandler(typeof(Shell), typeof(Test.Platforms.iOS.CustomAppShell));
#endif
            });
Enter fullscreen mode Exit fullscreen mode

Conclusion

In .NET MAUI it is really cool how easy you can implement a custom handler that allows to execute code based on each platform.

Thanks for reading! Follow me on social:

Top comments (4)

Collapse
 
dpasc014 profile image
Danny Pascual

Hello, thank you so much for uploading this to the web it was exactly what I was looking for. I only have one issue which is that it also changed the color of the tab which I did not want. I can't seem to figure out how to change it back to the original color while also keeping the removing of the iOS Navigation Bar Separator. If you can help me out with this, I'd greatly appreciate it. Thank you once again!

Here's a screenshot for reference:

Image description

Collapse
 
dpasc014 profile image
Danny Pascual

Never mind I was able to find the solution. Here's the code below:

navBar.TintColor = UIColor.Red;

Collapse
 
tonyedwardspz profile image
Tony Edwards

Thank for putting this together Victor 🙌

Collapse
 
alejotorresleon profile image
AlejoTorresLeon

I had a problem and it was that it overwrote the color of Shell.BackgroundColor and Shell.ForegroundColor already defined in my XAML, so I made this small modification and it worked perfectly for me.

using System.ComponentModel;
using Microsoft.Maui.Controls.Handlers.Compatibility;
using Microsoft.Maui.Controls.Platform.Compatibility;
using UIKit;

namespace Proyecto.Platforms.iOS
{
    public class CustomAppShell : ShellRenderer
    {
        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
        }
        protected override IShellTabBarAppearanceTracker CreateTabBarAppearanceTracker()
        {
            return new MyBottomNavViewAppearanceTracker();
        }
        protected override IShellNavBarAppearanceTracker CreateNavBarAppearanceTracker()
        {
            return new NoLineAppearanceTracker();
        }
    }

    public class NoLineAppearanceTracker : IShellNavBarAppearanceTracker
    {
        public void Dispose() { }
        public void ResetAppearance(UINavigationController controller) { }
        public void SetAppearance(UINavigationController controller, ShellAppearance appearance)
        {
            var navBar = controller.NavigationBar;
            var navigationBarAppearance = new UINavigationBarAppearance();
            navigationBarAppearance.ConfigureWithTransparentBackground();

            // Si hay color definido en el Shell, se convierte manualmente a UIColor
            if (appearance.BackgroundColor != null)
            {
                var color = appearance.BackgroundColor;
                navigationBarAppearance.BackgroundColor = UIColor.FromRGBA(
                    (nfloat)color.Red, (nfloat)color.Green, (nfloat)color.Blue, (nfloat)color.Alpha);
            }
            else
            {
                navigationBarAppearance.BackgroundColor = UIColor.Clear;
            }

            // Si se ha definido el ForegroundColor, lo aplicamos al texto del título y a los elementos de la barra
            if (appearance.ForegroundColor != null)
            {
                var fgColor = appearance.ForegroundColor;
                var uiFgColor = UIColor.FromRGBA(
                    (nfloat)fgColor.Red, (nfloat)fgColor.Green, (nfloat)fgColor.Blue, (nfloat)fgColor.Alpha);

                // Se configura el color del título
                navigationBarAppearance.TitleTextAttributes = new UIStringAttributes
                {
                    ForegroundColor = uiFgColor
                };

                // Se configura el color de los botones (por ejemplo, el botón Atrás)
                navBar.TintColor = uiFgColor;
            }


            // Quita la línea (underline) asignando la sombra a Clear
            navigationBarAppearance.ShadowColor = UIColor.Clear;

            navBar.ScrollEdgeAppearance = navBar.StandardAppearance = navigationBarAppearance;
        }
        public void SetHasShadow(UINavigationController controller, bool hasShadow) { }
        public void UpdateLayout(UINavigationController controller) { }
    }

    class MyBottomNavViewAppearanceTracker : IShellTabBarAppearanceTracker
    {
        public void Dispose() { }
        public void ResetAppearance(UITabBarController controller) { }

        // Implementa el método de la interfaz (solo 2 parámetros)
        public void SetAppearance(UITabBarController controller, ShellAppearance appearance)
        {
            var tabBar = controller.TabBar;
            var tabBarAppearance = new UITabBarAppearance();
            tabBarAppearance.ConfigureWithTransparentBackground();
            tabBarAppearance.ShadowColor = UIColor.Clear;

            // Conversión manual del color de fondo
            if (appearance.BackgroundColor != null)
            {
                var color = appearance.BackgroundColor;
                tabBarAppearance.BackgroundColor = UIColor.FromRGBA(
                    (nfloat)color.Red, (nfloat)color.Green, (nfloat)color.Blue, (nfloat)color.Alpha);
            }
            else
            {
                tabBarAppearance.BackgroundColor = UIColor.Clear;
            }

            tabBar.ScrollEdgeAppearance = tabBar.StandardAppearance = tabBarAppearance;
        }
        public void UpdateLayout(UITabBarController controller) { }
    }
}

Enter fullscreen mode Exit fullscreen mode