locked
How to use different Navigation Bar colors and background for each page in MasterDetail? RRS feed

  • Question

  • User393175 posted

    I have MasterDetailPage layout in my application.

    I use usual approach:

    ```xml

      >
      <x:Arguments>
        <pages:DashboardPage />
      </x:Arguments>
    </NavigationPage>
    

    ```

    The problem that when I use

    ```csharp var page = new NavigationPage(new AccountPage()) { BarBackgroundColor = Color.Red, BarTextColor = Color.White };

    await GetMasterDetailPage().Detail.Navigation.PushAsync(page); ```

    I'm having BarBackgroundColor and BarTextColor values from root NavigationPage.

    No matter the values I pass for new NavigationPage, always root navigation page colors are used.

    So, naturally, I'm using some kind of hack, now I use:

    ```csharp var page = new NavigationPage(new AccountPage()) { BarBackgroundColor = Color.Red, BarTextColor = Color.White }; ((NavigationPage) GetMasterDetailPage().Detail).BarBackgroundColor = page.BarBackgroundColor; ((NavigationPage) GetMasterDetailPage().Detail).BarTextColor = page.BarTextColor;

    await GetMasterDetailPage().Detail.Navigation.PushAsync(page); ```

    Which yes, changing the color, but I also need to implement then hack for BACK button, which would change Navigation Bar colors back, which visually shows user that in a matter of second color of Navigation Bar changes right in front of them. Which looks odd.

    Am I doing something wrong? How can I force Navigation Bar colors for each page in stack, so they would already be there in new pages.

    Update: it is also worth mentioning, iOS has neat feature of gradually changing colors when going to next page with Navigation Bar.

    It works with my hacky way only when opening new page, but does not when going back.

    Wednesday, March 11, 2020 12:58 PM

All replies

  • User369978 posted

    You don't need to hook the back event , just place the code into OnAppearing method in page , the color would set back if you reenter the page .

        // set different color in each page 
     protected override void OnAppearing()
        {
            base.OnAppearing();
    
            ((NavigationPage) GetMasterDetailPage().Detail).BarBackgroundColor = Color.Red;
        ((NavigationPage) GetMasterDetailPage().Detail).BarTextColor = Color.White;
        }
    

    Thursday, March 12, 2020 3:27 AM
  • User393175 posted

    @ColeX unfortunately it does not work for me for some reason. Only when I change before PushAsync it works.

    Anyway, the problem is also that if it would even work, color is not changed gradually when going back, because MasterDetailPage or root NavigationPage for some reason does not respect childrens colors. And my hacky way result in this:

    Thursday, March 12, 2020 8:50 AM
  • User369978 posted

    Why you push another navigation from current navigation page ? It would have two navigation bar there .

    Please check my sample below .

    Thursday, March 12, 2020 9:00 AM
  • User393175 posted

    @ColeX I don't understand about push another navigation from current navigation page.

    Ah! If you ask why I'm not using Navigation.PushAsync - I can't use this from Master page because it's not NavigationPage, so I coded NavigationService which pushes directly to Detail page. And I use it from everywhere.

    Anyway, your project has the same problems as my :(

    NavigationBar colors are not changing gradually but in instant, which looks bad on iOS:

    Thursday, March 12, 2020 9:21 AM
  • User369978 posted

    NavigationBar colors are not changing gradually but in instant, which looks bad on iOS:

    Oh yes , it's not a perfect solution ,just a workaround .

    Thursday, March 12, 2020 9:28 AM
  • User393175 posted

    @ColeX thanks for trying! The actual problem with all of this exactly that NavigationBar color changes without "morphing" into other color.

    As you can see in my Gif above, I got it changing gradually when going to new page. Because I set new color BEFORE PushAsync.

    I suspect I have to change color back BEFORE page is going back. Which means I have somehow to subsrcibe to event "BeforePageAboutToDissapear" or "UserSlidesPageBackEvent" on iOS.

    PageAppearing and PageDissapearing events are no-go for me because they are fired when page instantiated already and color changed AFTER page appeared.

    Thursday, March 12, 2020 9:50 AM
  • User393175 posted

    I managed to do this almost perfectly, though it's a hacky way and I want to transfer everything into the custom NavigationPage renderer code.

    It has problem, which is visible in this gif (if user decides to cancel going back color will be applied from previous page in stack to current page in stack, other than that everything works beatifully):

    I'm using custom NavigationPage renderer for iOS project and changing colors just before old ViewController would Pop. Here is my code for custom renderer:

    https://hastebin.com/vilegajobi.cs

    I'm still not sure how to change color of NavigationController.NavigationBar inside PushViewController, if I will be able to solve it I will paste here and resolve it. (right now I don't know how to change colors of navigation page in iOS project because I'm catching null errors about NavigationController.NavigationBar maybe I'm not getting it right)

    Thursday, March 12, 2020 11:27 PM
  • User369978 posted

    The viewController in PushViewController method is the target viewcontroller you'are going to push into navigation , so viewController.NavigationController should be null before it calls base.PushViewController(viewController, animated) , just use this instead of viewController.NavigationController .

    Friday, March 13, 2020 6:41 AM