Showing different toolbar buttons on each page with Xamarin Forms
Asked Answered
S

2

4

I have 2 pages in my Xamarin Forms app. My first page has 4 icons in the toolbar. My second page is a login page and has a tick and a cross in the toolbar.

I can't get the login page to show any icons unless I make it a navigation page. I also have to clear ToolBarItems on the first page before calling PushAsync() otherwise it complains there are too many toolbar items.

If I call PopAsync() on the login page it does not return to the first page. I'm guessing this is due to their being 2 navigation pages. I also tried PopToRootAsync().The back button works however.

My question is - how do I show different toolbar icons on 2 different pages in a way that allows navigation to work?

I'm testing this on Windows Phone 8.0

Here is the code calling the login page:

    private async void ShowLoginPage()
    {
        ToolbarItems.Clear();
        var page = new NavigationPage(new LoginPage());
        await Navigation.PushAsync(page);
    }

and here is the code to return to the first page:

    private void Cancel()
    {
        Navigation.PopToRootAsync();
    }

I'm running Xamarin.Forms v1.2.2.6243

Snafu answered 1/10, 2014 at 0:53 Comment(0)
K
1

One option that you have, and one that I implemented in my own app, is a custom renderer that removes the navigation header from the app and then you could build your own custom header. With this approach, you do lose some of the native feel of the app, and you have to implement much of the transitional functionality your self. However, it gives you alot more control over the look.

CustomRenderer that removes the navigationBar:

//add using statements

// add all view here that need this custom header, might be able to build a 
//base page that others inherit from, so that this will work on all pages.
[assembly: ExportRenderer(typeof(yourView), typeof(HeaderRenderer))] 

class HeaderRenderer : PageRenderer
{
    public override void ViewWillAppear(bool animated)
    {
        base.ViewWillAppear(animated);
        this.NavigationController.SetNavigationBarHidden(true, true);
    }
}

After this you can build a header view that can be placed on the top of every page (I am using xaml) so I don't know if it is relevant in you application.

Edit: You might need to change this renderer for differnt page types.

Kazukokb answered 2/10, 2014 at 20:48 Comment(8)
Sounds interesting. Will investigate.Snafu
if you need any more help with an implementation let me know.Kazukokb
ViewWillAppear does not seem to be available as an overrideable method. Neither is ViewDidAppear. Any ideas?Snafu
@SteveChadbourne what renderer are you extendingKazukokb
I'm guessing this is on iOS. I'm on Android. I'm extending PageRenderer.Snafu
Ya this is iOS I'm not sure how it would work on androidKazukokb
@SteveChadbourne I think the android equivalent is onCreate or onResumeKazukokb
Very old post, but do you think could send a sample with this workingPortingale
M
4

One thing you could try is to keep your Login Page inside of a NavigationPage, and then instead of running PopAsync() within the Login Page after they have logged in successfully, simply replace the MainPage with your old Navigation page:

In your App class:

public NavigationPage AppNavPage = new NavigationPage(new FirstPage());

public App() {
    MainPage = AppNavPage;
}

In your FirstPage:

private async void ShowLoginPage() {
    ToolbarItems.Clear();
    var page = new NavigationPage(new LoginPage());
    await Navigation.PushAsync(page);
}

In Login Page:

private async void OnCreateClicked(object sender, EventArgs e) {
    bool loginInfoIsGood = CheckLoginInfo(); //Check their login info

    if(loginInfoIsGood) {
        Application.Current.MainPage = App.AppNavPage;
    }
}

Otherwise, I have also done a custom renderer for the NavigationRenderer on iOS to insert toolbar items onto the right side of the Navigation Bar and have overridden some Menu related stuff on Android to change the icon text/colors.

Marsden answered 3/9, 2015 at 18:22 Comment(0)
K
1

One option that you have, and one that I implemented in my own app, is a custom renderer that removes the navigation header from the app and then you could build your own custom header. With this approach, you do lose some of the native feel of the app, and you have to implement much of the transitional functionality your self. However, it gives you alot more control over the look.

CustomRenderer that removes the navigationBar:

//add using statements

// add all view here that need this custom header, might be able to build a 
//base page that others inherit from, so that this will work on all pages.
[assembly: ExportRenderer(typeof(yourView), typeof(HeaderRenderer))] 

class HeaderRenderer : PageRenderer
{
    public override void ViewWillAppear(bool animated)
    {
        base.ViewWillAppear(animated);
        this.NavigationController.SetNavigationBarHidden(true, true);
    }
}

After this you can build a header view that can be placed on the top of every page (I am using xaml) so I don't know if it is relevant in you application.

Edit: You might need to change this renderer for differnt page types.

Kazukokb answered 2/10, 2014 at 20:48 Comment(8)
Sounds interesting. Will investigate.Snafu
if you need any more help with an implementation let me know.Kazukokb
ViewWillAppear does not seem to be available as an overrideable method. Neither is ViewDidAppear. Any ideas?Snafu
@SteveChadbourne what renderer are you extendingKazukokb
I'm guessing this is on iOS. I'm on Android. I'm extending PageRenderer.Snafu
Ya this is iOS I'm not sure how it would work on androidKazukokb
@SteveChadbourne I think the android equivalent is onCreate or onResumeKazukokb
Very old post, but do you think could send a sample with this workingPortingale

© 2022 - 2024 — McMap. All rights reserved.