Lets say the first page in the app is the login page and then it takes me to do the main menu screen, is there a way to get rid of the back button in the main menu navigation bar, like get rid of the login page stack?
thank you
In Xamarin.Forms 1.3 and greater you can use
NavigationPage.SetHasBackButton(this, false);
In Xaml you can add:
<ContentPage ....NameSpaces etc....
NavigationPage.HasBackButton="False"
Title="MyPage">
</ContentPage>
You can avoid having the Back button if you replace the Navigation.PushAsync(page) to Navigation.PushModalAsync(page) in your login page's code. Post some code if this somehow doesn't apply
This has to do with how navigation works in the underlying OS (at least in iOS that's the case) - there is a Navigation Controller which serves for pages to transition between each other and have a trace of previous screen so the user can go back.
There are 2 ways to get rid of back button:
1) You can remove navigation bar from Xaml using Xamarin.Forms using below code
NavigationPage.SetHasNavigationBar (this, false);
Where this stands for current page / form instance.
2) Follow below mentioned steps
Navigate to login page when the app is loaded with Normal ContentPage instance of Login Page
Navigate to Main page from Login page using PushModalAsync and provide the main page instance as NavigationPage
And then from all the other pages, you can use PushAsync and it'll let you navigate to all the pages without any error.
Hope this helps!
By using CustomRenderer, you call this function in ViewWillAppear in your customized view controller
public override void ViewWillAppear (bool animated)
{
base.ViewWillAppear (animated);
this.ParentViewController.NavigationItem.SetHidesBackButton (true, false);
//remember to use ParentViewController to reference to the NavigationViewController (if your contentPage is direct under a navigation controller. I don't know why but Xamarin must have a bug with SetHidesBackButton. If you call with this.NavigationItem.SetHidesBackButton(...), it should not work.
... other implements here ...
}
Related
Using Xamarin.Forms v4.5 and Prism v7.2
I have an APP with 3 pages (PageA, PageB and PageC).
From PageA, I can navigate to PageB and from PageB to PageC. From PageC, I can tap on the back button and go back to PageB.
My question is, when I navigate to PageB (either from PageA or PageC), is there a method that Prism provides to identify whether I end up to PageB by pressing the back button?
At this time Xamarin.Forms does not provide a way to hook into the underlying Navigation Service and intercept the full Navigation process in certain flows such as when someone clicks on a hardware back button. As a result we are limited in what we can do and are therefore not able to support IConfirmNavigation to allow you to prevent navigating away.
That having been said we are able to observe that a Page was popped and we are still able to invoke OnNavigatedFrom/OnNavigatedTo. You can easily determine what has occurred by getting the NavigationMode. To do this your code might look like this:
public void OnNavigatedTo(INavigationParameters parameters)
{
var mode = parameters.GetNavigationMode();
switch(mode)
{
case NavigationMode.New:
break;
case NavigationMode.Back:
break;
case NavigationMode.Forward:
break;
}
}
When I return to the Root Page with this method:
Page page = (Page)Activator.CreateInstance(typeof(TrasfMagaPage), session);
Navigation.InsertPageBefore(page, Navigation.NavigationStack[0]);
await Navigation.PopToRootAsync(true);
The icon of the hamburger menu disappears from the TopBar.
I use the same code with all the other pages, but only in this case it presents the problem.
How is that possible?
I have written code similar to this to prevent a white flicker that appears in Android master detail pages. When inserting a page before the root, I use the Navigation of the Detail page.
Detail.Navigation.InsertPageBefore(page, root);
await Detail.Navigation.PopToRootAsync(false);
I am developing a Xamarin.Forms app with Prism in which I'd like to incorporate an onboarding page (more specific a top user benefits page, following the Material Design guidelines).
The app itself is structured around a NavigationPage to which I navigate with
NavigationService.NavigateAsync("/NavigationRootPage/MainPage")
in my App(). On the first start I'd like to show the onboarding page instead and I am having quite some issues getting it right.
My first approach was to navigate to MainPage with
_navigationService.NavigateAsync("/NavigationRootPage/MainPage")
from my viewmodel, when the user clicks the Get Started! button. This kind of worked by is also kind of ugly, since this absolute navigation will destroy the oboarding page immediately and not animate the transition. Furthermore at the moment the oboarding page is destroyed, the MainPage will be built, which will take a small, but noticeable, amount of time. In effect the user will notice the MainPage being built up, which does not look smooth at all.
My second approach was to navigate in a relative fashion from my viewmodel.
_navigationService.NavigateAsync("NavigationRootPage/MainPage")
This works way smoother, with the transition animation and after the animation is done, the MainPage is already ready to go. But again there is a major drawback. You can navigate back to the onbaording page, which we dont't want neither. And - to my knowledge - there is no (clean) way to remove the page from the navigation stack, too. I tried calling PageUtility.DestroyPage on my onboarding page, but this only worsened things, since it seemed to keep the page, but destroy the viewmodel, resulting in my onboarding page being shown without data when pushing the back button.
My third approach did not work at all, although it seemed promising to me. In my App() I pushed my navigation page with the main page then then my onboarding page modal
NavigationService.NavigateAsync("/NavigationRootPage/MainPage");
NavigationService.NavigateAsync("OnboardingPage", useModalNavigation: true);
and then in my viewmodel
_navigationService.GoBackAsync(useModalNavigation: true)
but this approach
showed the header of the NavigationPage although the onbaording page was supposed to be shown as a modal
refused to GoBackAsync - when calling this method, nothing happens
waiting for the first call to NavigateAsync did not change anything either.
Some other things I've tried
Implemented INavigationOptions in my viewmodel with ClearNavigationStackOnNavigation being true
Tried setting Application.MainPage after my NavigationPage was shown, but to no avail
I would have believed that this was king of a common requirement when programming an app. Is there something I've missed? Or will I have to live with one of those drawbacks?
I think you are overthinking this. If you want to show your Onborading page first then just navigate to it first.
`NavigateAsync("NavigationPage/OnboardingPage");
Or if you want to have the MainPage in the stack, then start the app with a deeplink
`NavigateAsync("NavigationPage/MainPage/OnboardingPage");
If you don't want to show the navigation header, just hide it for the onboarding page.
Don't use an absolute navigation unless you want to completely reset the navigation stack (equivalent to MainPage = new MainPage()).
I have found a solution, which is not the most beautiful one (it is actually quite ugly) but working.
In my MainPages viewmodel I implemented INavigatingAware and navigated to my OnboardingPage modally
public async void OnNavigatingTo(NavigationParameters parameters)
{
await _navigationService.NavigateAsync("LandingPage", useModalNavigation: true);
}
However, removing the moal page with
this._navigationService.GoBackAsync(useModalNavigation: true);
does not work as expected. The modal is not removed (although it should work this way from looking at the code, but I did not manage to debug with Re# generated PDBs). Hence I had to go the ugly (non-MVVM) way and create an event handler for Button.Click and remove the modal manually
private void Button_OnClicked(object sender, EventArgs e)
{
this.Navigation.PopModalAsync();
}
This will return to my MainPage smoothly with an animation and my MainPageis already up and running without being built up while already visible.
Still, I'd appreciate an answer on how to do it the Prism way.
When I want to hide navigation bar with my menu, I can't.
NavigationPage.SetHasNavigationBar(this, false);
I want confirmation is that a bug or I something overlooked?
If it isn't working I'd check to make sure the page you are trying to hide it in is actually being pushed in a NavigationPage().
Calling NavigationPage.SetHasNavigationBar(this, false); in cs right after InitializeComponent(); should work unless something else you have is incorrect.
Or you could instead try setting it directly in xaml of the page with NavigationPage.HasNavigationBar="False"
I use the following code to start a freshhmvvm master-detail page from a list in a navigation page. This works fine, but the user can not go back to the list page on IOS. On android it is possible using the system back-button from each detailpage.
Does this mean I have to add a 'Back' button to each detailpage to make this work on IOS?
Or are there other ways to start a masterdetail in freshmvvm?
var masterDetailNav = new FreshMasterDetailNavigationContainer();
masterDetailNav.Init("Menu");
masterDetailNav.AddPage<FirstPageModel>("First", item);
masterDetailNav.AddPage<SecondPageModel>("Second", item.id);
await CoreMethods.PushNewNavigationServiceModal(masterDetailNav);