Skip to content

Custom App Header in Forms

iOS Navigation Bar NestedIt is safe to assume that any business with a customer facing application will want to brand their application with at least their logo. From the very onset of using Xamarin.Forms, I found myself annoyed with the lack of customizability of the navigation bar for iOS. To be fair, it is a pain to customize on the native side; however, the Forms’ abstraction removes most of your options.

NOTE: the navigation bar shows up when a Page is nested within a NavigationPage; this creates a navigation stack.

The equivalent implementation for Android is a toolbar or action bar. Within the Android project, you can customize the toolbar using the native Toolbar.axml layout file. Unfortunately, in order to customize the iOS navigation bar to the same extent as Android requires a custom renderer and a fair amount of hacking. Even with the ability to manipulate the look of the iOS navigation bar using a custom renderer, both platforms are now diverging from each other (not to mention if you support Windows). This messy solution wasn’t going to work for me. Two simple features resolved this dilemma.

I came to the realization that I could not use the navigation bar (iOS) or toolbar (Android) and maintain a unified solution between platforms. Simply put, I wanted the platform specific bars to disappear. Thankfully, Xamarin provides a simple way to turn them off. Using the static reference to NavigationPage provides the method SetHasNavigationBar. This method takes two parameters, the page the setting applies to and the boolean value.

At this point my navigation stack no longer has a header. This allows me to add a completely custom implementation that will work for all platforms. An easy way to create such a header is with the combination of a boxview, a back button, and a logo. The specifics are not important because it will vary greatly between applications. An example could look like the following:

But how do I apply this XAML to each of my pages?! This can be accomplished with a ControlTemplate. A ControlTemplate is a UI template that can be applied to any XAML page. You’ll define the template in the ResourceDictionary located in the App.xaml file. You will also include a ContentPresenter within the template. A ContentPresenter is the content area or body of the pages the template is being applied to. The ControlTemplate Key will be used to reference the template in your pages.

Once the ControlTemplate is created, we need to apply it to our Pages. This is accomplished by adding a StaticResource reference of the template Key inside our pages’ ControlTemplate property in the XAML.

iOS Custom App HeaderYou now have a fully customizable header for your application. You can add EventHandlers, Commands, or GestureRecognizers to interact with your header as needed. You will have to implement the back button logic as well.

Published inFormsUIXamarin
  • Pingback: Creating a hamburger menu in Xamarin.Forms – Wolf Programmer()

  • Luke Alderton

    Thanks for the help on this.

  • Stefan Riedmann

    Very nice, but…. unfortunately the page for which I want a customized header, is a TabbedPage, which cannot be embedded in a ContentPage or any TemplatedPage… I’ll have to use a CarousselView instead of a TabbedPage inside my customized “navigation” page.

    • Richard TORRE

      Totally agree, that solution only works if we use ContentPage. Once you have to deals with tabbedPage, MasterDetailPage, you’ll face that problem again.

  • John Watts

    How can you customize the navigation bar when using Xamarin native iOS development rather than Xamarin.Forms? I cant seem to find this information anywhere.

  • Dino Novak

    Hello Thomas,
    I found this article quite interesting, and would like to find the way if this approach can be combined with “”

    As hamburger menu is relying on Navigationbar is it possible to do so?

  • Peter Kujawski

    Cool stuff and seems simple but what about if I have a tabbed page? And what if stack changes so that arrow is no longer needed, how would I go about making it disappear depending on the nav stack?