PrismLibrary / Prism

Prism is a framework for building loosely coupled, maintainable, and testable XAML applications in WPF, Xamarin Forms, and Uno / Win UI Applications..
Other
6.32k stars 1.64k forks source link

Expected Behavior of Back Button on Navigation Page #344

Closed billSpaulding closed 8 years ago

billSpaulding commented 8 years ago

Hello,

Ive been working with your newest navigation sample for a couple of days now. Great job! It has helped reduce complexity in our project by a considerable amount. Thank You.

Question: if I have a navigation flow such as the following MyMasterDetail/MyNavigationPage/ViewA

what is the difference in using the back button on the navigation page and the go back method on the PRISM Navigation Service to move from ViewA to MyNavigationPage. Do I need to handle the button press? Are the same events fired? Will they both remove the page from the stack?

Thank You, Bill

brianlagunas commented 8 years ago

Calling NavigationService.GoBack and hitting the back button do the exact same thing. The only difference is, for the moment, the INavigationAware methods don't get called when using the back button. I hope to fix that soon.

By the way, you don't go from ViewA to the NavigationPage. Your ViewA is the root of the NavigationPage, so if you call GoBack from ViewA, nothing will happen. Now, if you call GoBack from MyNavgationPage then you will exit the app because you just popped modal the MasterDetail.

billSpaulding commented 8 years ago

yes that is what brought up the question. just wanted to make sure I wasn't somehow on a different navigation stack. thank you for that clarification.

billSpaulding commented 8 years ago

Hello,

what behavior should I expect here?

if I have a navigation flow such as the following MyMasterDetail/MyNavigationPage/ViewA

Then from ViewA I navigate to ViewB by setting the use modal flag to true resulting in this flow MyMasterDetail/MyNavigationPage/ViewA/ViewB

Then I navigate back to ViewA by using the GoBack() on the nav service ending in this flow MyMasterDetail/MyNavigationPage/ViewA/

Question: Should I expect the onNavigatedTo event to fire on ViewA when ViewB calls GoBack()?

the scenario is essentially a user using a master detail page to navigate to a customer list which is hosted in a nav page. from there they navigate to a specific customer "ViewA" and from there a subset of information on the specific user "ViewB"

If the answer is YES was this a recent commit?

Thank You, Bill

brianlagunas commented 8 years ago

This is correct. Since ViewA was the view you navigated to by calling GoBack, then INavigationAware is called on ViewA. It wouldn't make sense to call INavigationAware methods on any other view that was not the target of the navigation.

No, this is how it should always behave.

billSpaulding commented 8 years ago

the response time on this forum is incredible. thank you for that.

on the topic of navigation is there an option available to pass an instance of a page? as an example if ViewB in the above scenario has very expensive resources with potentially lengthy initialization for reasons beyond my control (3rd party api) that I would prefer to reuse rather than create/dispose. can I reuse a page instance like is possible with XF.Navigation

brianlagunas commented 8 years ago

There will never be an option to pass a page type via navigation, but in a future version there will be a way to cache pages for use during navigation.

billSpaulding commented 8 years ago

"but in a future version there will be a way to cache pages for use during navigation." this would be fantastic thank you,

billSpaulding commented 8 years ago

Earlier you said: "This is correct. Since ViewA was the view you navigated to by calling GoBack, then INavigationAware is called on ViewA. It wouldn't make sense to call INavigationAware methods on any other view that was not the target of the navigation."

I am not observing this behavior. (last build I grabbed from GIT was about 10 days ago) in the code below in App.cs I navigate to the UserContactListView and its OnNavigatedToEvent is fired as expected. When navigating to UserContactRequestListView from UserContactListView and calling GoBack() to return to UserContactListView its OnNavigatedTo is not fired which I did expect to happen based on your response.

here is the complete process. I'm guessing I either have something wrong or misinterpreted your response

CALLED IN APP.CS await NavigationService.Navigate("RootMasterDetailView/MainNavigationView/UserContactListView");

CALLED IN USERCONTACTLISTVIEWMODEL.CS _navigationService.Navigate("UserContactRequestList", useModalNavigation:true);

CALLED IN USERCONTACTREQUESTLISTVIEWMODEL.CS _navigationService.GoBack();

brianlagunas commented 8 years ago

Hmmm... I'll test that out on as soon as I can. There could be a bug there with the GoBack. The logic to determine how to find the previous page in the stack may be flawed. I have a busy day tomorrow so I won't be able to look at this until Sunday.

Since you are running from source, if you have time to debug through the GoBack logic that would be very helpful. If you find the issue, you can also submit a fix :)

billSpaulding commented 8 years ago

no problem. ill let you know what i find or that i fixed my own issue :-)

billSpaulding commented 8 years ago

I was unable to reproduce this using the sample XF solution. the implementation is straight forward enough. for whatever reason my solution has poppedPage as null. I have no idea why but this doesn't appear to be an issue with PRISM

var poppedPage = await DoPop(page.Navigation, useModalForDoPop, animated);

        if (poppedPage != null)
            OnNavigatedTo(previousPage, segmentParameters);

I'm wondering if I'm possibly using the Navigation Service in a manner that is not valid. Is the following process correct?

this is from App.cs and its the first time the Nav service is invoked. the intent is to load the apps main master detail view a navigation view and a content page for the navigation view await NavigationService.Navigate("RootMasterDetailView/MainNavigationView/DashboardView");

Now if the user opens the menu page for the master detail view (rootMasterDetailView) and clicks a menu item to navigate to their contact list is it valid to do the following (leave off 'RootMasterDetailView/' from the uri) with the intent on NOT having to reload to master detail view. this is being called from the MainNavigationViewModel await NavigationService.Navigate("MainNavigationView/UserContactListView");

and then from there if the user wants to see a detail view of a contact within the contact list they click a list item and they navigate to the UserProfileDetailView using this Navigation call originating from the above targets view model (UserContactListViewModel) await NavigationService.Navigate("UserProfileDetailView");

didn't spend a lot of time with it but on a first pass of the above implementation it does appear to allow the masterdetailview to not have to be reloaded and all works as expected aside from not having the menu icon for the masterdetailview that is used to open the menu

brianlagunas commented 8 years ago

Remember, navigation is always relative to where you are calling Navigate().

If you open the menu from MasterDetailPage to navigate, then you must call navigate from the MasterDetailPageViewModel in order to replace the Detail with the target view.

Calling Navigate() from your MainNavigationViewModel will not be replacing the Detail of the MasterDetailPage, but rather navigating another page onto the MainNavigationView navigation stack. Also, if you are calling NavigationService.Navigate("MainNavigationView/UserContactListView"); from your MainNavigationViewModel, then you are actually adding another NavigationPage that navigates to your UserContactListView to your stack. Remember, your target is relative to where you are calling Navigate.

So, if you want to push another page onto your MainNavigationView, then you simply call Navigate("TheOtherView"); from your MainNavigationViewModel.

billSpaulding commented 8 years ago

Hi Brian, hopefully they give you a day off now and then!

Ok my problem was clearly not understanding the mechanics of the navigation service. your reply makes perfect sense. Thank you very much for the continued help

billSpaulding commented 8 years ago

After spending some time reviewing your response I realized I had initially misinterpreted it. I wasn't clear on exactly what you meant by navigating from MainNavigationView. You wrote : "So, if you want to push another page onto your MainNavigationView, then you simply call Navigate("TheOtherView"); from your MainNavigationViewModel."

Based on the sample solution I am assuming you meant if I wanted to push an additional page onto the stack I would simply call navigate from the content pages viewmodel (one hosted in the navigation page) and not on MainNavigationViewModel which in my solution is the same as MyNavigationPageViewModel in the XF sample. In the sample no navigation is executed from that page only in the master detail and the actual content pages that are loaded into the navigation page.

which means I still have a problem with onNavigatedTo not being called when closing a modal. I am able to reproduce the issue with the sample slightly modified

In the sample XF solution App.cs calls NavigationService.Navigate("MyMasterDetail/MyNavigationPage/ViewA");

change ViewAViewModel Nav method to: _navigationService.Navigate("ViewB", useModalNavigation:true);

change ViewBViewModel Nav method to: _navigationService.GoBack(useModalNavigation: true);

Navigate to ViewB then back to ViewA and ViewAViewModel's onNavigatedToEvent does not fire. the reason is the method below returns null for the previous page. the issue appears to be here

--------snippet from method below----- MODALSTACKCOUNT EVALUTES TO 1 AS EXPECTED int modalStackCount = page.Navigation.ModalStack.Count;

THIS LINE WILL RESULT IN PREVIOUSPAGEINDEX BEING ASSIGNED A VALUE OF -1 (modal stack count of 1 - (-2)) int previousPageIndex = modalStackCount - 2;

THIS LINE WILL ALWAYS EVALUATE TO FALSE DUE TO PREVIOUSPAGEINDEX being >0 if (modalStackCount > 0 && previousPageIndex >= 0)

-------snippet from method below------

FROM PageNavigationService.cs static Page GetPreviousPage(Page page, bool useModalNavigation) { Page previousPage = null;

        if (useModalNavigation)
        {
            int modalStackCount = page.Navigation.ModalStack.Count;
            int previousPageIndex = modalStackCount - 2;
            if (modalStackCount > 0 && previousPageIndex >= 0)
            {
                previousPage = page.Navigation.ModalStack[previousPageIndex];
            }
        }
        else
        {
            int navStackCount = page.Navigation.NavigationStack.Count;
            int previousPageIndex = navStackCount - 2;
            if (navStackCount > 0 && previousPageIndex >= 0)
            {
                previousPage = page.Navigation.NavigationStack[previousPageIndex];
            }

            if (previousPage == null)
                previousPage = GetPreviousPage(page, true);
        }

        return previousPage;
    }
brianlagunas commented 8 years ago

That is probably happening because you are going from a modal stack to a non modal. I'll have to research that.

I do find it odd that you are navigating modal from a NavigationPage. Not sure that makes sense from a mobile navigation perspective.

billSpaulding commented 8 years ago

you wrote: "I do find it odd that you are navigating modal from a NavigationPage"

I didn't think I was but its also very possible I have some concepts mixed up. Its to my understanding that in XF if I want to load a page into the detail property of a master detail page and I want to be able to navigate to other pages from that page then it must be a navigation page.

so in my scenario I load the master detail , the navigation page and a content page RootMasterDetailView/MainNavigationView/UserContactListView

once I'm on UserContactListView there are navigation options that use both true/false for modal. if the user is looking at their contact list and they have pending contact requests a link is present. this is just a one page view that has a list of requests and an accept/decline button. it doesn't navigate to any other page so I use modal = true. and GoBack(modal = true) to return from it

from the same UserContactListView the user may select a contact from the list. in this scenario I use modal = false because the page they are going to UserProfileDetailView has additional navigation options so I use non modal navigation. from the UserProfileDetailView the user may elect to see a map view, a street view or a list of notification options all accessed via modal screens.

In general I looked at modal like I would a flyout or popup control and non modal for actual pages. if this is not correct please let me know.

I still wouldn't be surprised if I'm just not getting something but in the GoBackMethod() the result of the call to GetPreviousPage() is passed to OnNavigatedTo(previousPage, segmentParameters);

wouldn't we want to pass in the page that is the target of the navigation and not the page that was just popped off the modal stack?

billSpaulding commented 8 years ago

taking a closer look at GetPreviousPage() on the PageNavigationService and I see how it works flawlessly for non modal navigation. However when using modal navigation it seems that we cant actually get a handle on the previous page regardless of the usemodal flag. When entering the method after invoking GoBack() from a modal neither the modal stack nor the nav stack contains the actual last page. The only page that appears to be accessible is the last modal that was opened. It would seem that we would need access to the page that called Navigate(modal = true) because that is the page instance that needs to be passed to OnNavigatedTo method of PageNavigationClass for its OnNavigatedToEvent to fire.

out of curiosity why do we set the modal stack count variable to -2? To me that is implying that we think both the content page and the modal page are in the same stack but I really haven't spent much time looking at it. I know that XF treats both as individual navigation stacks. It almost seems like we are working with a different Navigation context in this method because I am unable to see the page that invoked the modal.

static Page GetPreviousPage(Page page, bool useModalNavigation) { Page previousPage = null;

        if (useModalNavigation)
        {
            int modalStackCount = page.Navigation.ModalStack.Count;
            int previousPageIndex = modalStackCount - 2;
            if (modalStackCount > 0 && previousPageIndex >= 0)
            {
                previousPage = page.Navigation.ModalStack[1];
            }
        }
        else
        {
            int navStackCount = page.Navigation.NavigationStack.Count;
            int previousPageIndex = navStackCount - 2;
            if (navStackCount > 0 && previousPageIndex >= 0)
            {
                previousPage = page.Navigation.NavigationStack[previousPageIndex];
            }

            if (previousPage == null)
                previousPage = GetPreviousPage(page, true);
        }

        return previousPage;
    }
billSpaulding commented 8 years ago

the following code would appear to address the issue with not passing the correct 'previous page'. not sure its the most elegant but it does get the events to fire as expected

if we could add this to the GoBack() method as the function that gets the previous page that is passed to OnNavigatedTo

the intent here is to get a reference back to the viewmodel that called navigate(modal = true) so that we can fire its on navigatedto event when the modal is closed

var page = GetCurrentPage();

        PrismApplicationBase  MyPRISMApp = (PrismApplicationBase)page.Parent;
        MasterDetailPage MyDetailPage = (MasterDetailPage)MyPRISMApp.MainPage;
        NavigationPage MyNavigationPage = (NavigationPage)MyDetailPage.Detail;
        var canNavigate = await CanNavigateAsync(page, segmentParameters);

OnNavigatedTo(MyNavigationPage.CurrentPage, segmentParameters);

brianlagunas commented 8 years ago

The suggested code is very specific to this particular navigation stack and will not work for every other possible navigation scenario. I will have to think about the problem more in depth while considering all navigation scenarios and see of I can think of a solution.

billSpaulding commented 8 years ago

agreed. I have been thinking about other scenarios that may be impacted. not sure if its a simple overload/flag for this one use case or if the permutations would get out of hand. Considering MasterDetail page is one of the most common navigation patterns I think it probably should be supported somehow especially if the nav service allows for it from a navigation standpoint.

but this problem I don't feel is specific to masterdetail if I'm not mistaken its going to surface any time someone uses modal navigation and then calls GoBack(). If your on ViewA and you invoke the navigation service with modal = true to get to ViewB when you call GoBack from ViewModelB OnNavigatedTo on ViewModelA will not fire because the incorrect 'previous' page gets passed to OnNavigatedTo in the PageService class. combine this with Xamarin not having hooks into the back button on the Nav page so we can also fire OnNavigatedTo on that click event results in having to implement a number of workarounds or rethink navigation. PRISM offers the same nav concepts across all clients that's one of the reasons I love it!

if I come across any other use cases for GoBack ill share them

thanks again

billSpaulding commented 8 years ago

i have some time over the next few days and would be happy to help in anyway i can. if you agree with either approach below i can spend some time developing them.

1)have the user pass in a 2nd parameter when setting modal = true. the 2nd parameter would express the page type that they navigated from. that will be needed by the PageService class to determine which processing logic to apply to get the correct page. so the method would largely stay the same aside from maybe a switch statement that evaluates the new page type parameter so that it can invoke the corresponding logic to get the needed page. haven't thought it through but I'm guessing there would be 1-3 scenarios supported by 1-3 helper methods encapsulating code like i presented above

assumption: i have only deployed a solution using XF and PRISM to IPHONE. I am assuming that the modal = true parameter is the same on IPHONE and ANDROID in that from the users perspective the page slides in from bottom opposed to sliding in left to right beyond that there is no difference. On WINDOWS PHONE i don't think it has an impact.

2) If the assumption is true then it may be possible to just have the modal parameter control how the page is presented to the user. slide left to right / slide in from bottom. if I'm not mistaken goback would then work in every scenario. my code above is only needed because there is no reference to the page i initiated navigation from when using modal. whether there are hooks for this or not is something i have no clue about.

brianlagunas commented 8 years ago

No page types allowed in a VM. This is actually more complicated than you may think initially. Also, just because you are going back modally doesn't mean that the target is a modal view and there is no telling how deep the navigation stack goes. But, you may want to actually go back to a modal view. Considering the many different types of pages, each handling children differently and each having its own navigation stack, things get more complicated by the minute :)

Ideally, the signature of the GoBack method should not change.

billSpaulding commented 8 years ago

very good points. its funny i was just thinking that you probably had a similar conversation with yourself after you started on the multiple nav scenario features!

as for page types i was referring to a string representation that is nothing more than an indicator for the PageNavigationService to infer what the page type of the target navigation is

for clarity i am not navigating from one modal to another at anytime if that is what you meant by " Also, just because you are going back modally doesn't mean that the target is a modal view"

my scenarios are all MasterDetail>NavigationPage>TheContentPageOfTheNavigationPage> and then to a modal. when using modal it is always from a content page and directly back. one push / one pop.

ok i will give this some thought and see if i can come up with anything

brianlagunas commented 8 years ago

Can't rely on string types, as there can be many instances of the same type on the nav stack. Also, a modal nav can happen from any page type not just content pages. I have an idea of how I will solve this. I still need to think this through though.

billSpaulding commented 8 years ago

i think this is going in the right direction. so far it has handled all cases ive tried and it does not impact the existing GoBack() method

a few assumptions

could call the method below from the previousPage method replacing the logic for modal navigation


static Page GetPreviousPage(Page page, bool useModalNavigation) { Page previousPage = null;

        if (useModalNavigation)
        {
            //int modalStackCount = page.Navigation.ModalStack.Count;
            //int previousPageIndex = modalStackCount - 2;
            //if (modalStackCount > 0 && previousPageIndex >= 0)
            //{
            //    previousPage = page.Navigation.ModalStack[1];
            //}
            previousPage = GetBackNavigationTargetForModalPage(page);
        }
        els

static Page GetBackNavigationTargetForModalPage(Page page) { //create a Page variable to hold our response Page previousPage = null; //get an instance to the current PRISM application PrismApplicationBase MyPRISMApp = (PrismApplicationBase)page.Parent;

        Type thePageType = MyPRISMApp.MainPage.GetType();
        string test = thePageType.GetTypeInfo().BaseType.ToString();
        //determine the page type of the current page of the current application
        switch (thePageType.GetTypeInfo().BaseType.ToString())
        {

            //evaluate the case statements to find a match and execute the appropriate logic for deriving the 
            //modal navigation target
            case "Xamarin.Forms.ContentPage":
                //a content page has no other possible associated pages
                previousPage = MyPRISMApp.MainPage;
                break;
            case "Xamarin.Forms.NavigationPage":
                //cast to a navigation page type
                NavigationPage TargetNavigationPage = (NavigationPage)MyPRISMApp.MainPage;
                //set the previous page to the navigation page's current page
                previousPage = TargetNavigationPage.CurrentPage;
                break;
            case "Xamarin.Forms.TabbedPage":
                //cast to a tabbed page type
                TabbedPage MyTabbedPage = (TabbedPage)MyPRISMApp.MainPage;
                Type tabbedPagePageType = MyTabbedPage.GetType();
                //a tabbed page may contain either a content page or a navigation page
                //we check for both scenarios
                if (tabbedPagePageType.GetTypeInfo().BaseType.ToString() == "Xamarin.Forms.NavigationPage")
                {
                    //cast to a navigation page type
                    NavigationPage MyNavigationPage = (NavigationPage)MyTabbedPage.CurrentPage;
                    //set previous page response to the current page of the Navigation Page
                    previousPage = MyNavigationPage.CurrentPage;
                }//in this scenario the tabbed page contains a simple content page
                else if (tabbedPagePageType.GetTypeInfo().BaseType.ToString() == "Xamarin.Forms.ContentPage")
                {
                    //set the previousPage response to the tabbed page current content page
                    previousPage = MyTabbedPage.CurrentPage;
                }
                break;
            case "Xamarin.Forms.MasterDetailPage":
                //cast to a MasterDetail page type
                MasterDetailPage MyDetailPage = (MasterDetailPage)MyPRISMApp.MainPage;
                Type masterPageDetailPageType = MyDetailPage.Detail.GetType();
                //the MasterDetail page type can contain either a Navigation Page or a Content Page
                //we test for both
                if (masterPageDetailPageType.GetTypeInfo().BaseType.ToString() == "Xamarin.Forms.NavigationPage")
                {
                    //cast to a navigation page
                    NavigationPage MyNavigationPage = (NavigationPage)MyDetailPage.Detail;
                    //set the previousPage response to the current page of the NavigationPage
                    previousPage = MyNavigationPage.CurrentPage;
                }
                else if (masterPageDetailPageType.GetTypeInfo().BaseType.ToString() ==  "Xamarin.Forms.ContentPage")
                {
                    //set the previousPage response to the content page of the MasterDetailPage.Detail
                    previousPage = MyDetailPage.Detail;
                }
                break;
        }
       // return the response;
        return previousPage;
    }
brianlagunas commented 8 years ago

Hate to burst your bubble, but all of those assumptions are incorrect. Every one of those is possible and actually should be expected. You cannot base your logic on the application MainPage. It has to be relative to the page calling GoBack, which may not be the current visible page.

brianlagunas commented 8 years ago

The first step should be finding the position of the current page in the proper stack. Then find the page prior to it in the stack. Then iterate over the prior pages modal and nav stack to find the proper page to call OnNavigatedTo

billSpaulding commented 8 years ago

this Application.Current.MainPage; returns a different object than this PrismApplicationBase MyPRISMApp = (PrismApplicationBase)page.Parent;

the 2nd one returns the page you called from. the first one appears to return the nav stack of the page that was navigated to. if you navigate to ViewB from ViewA using modal=true the nav stack returned from Application.Current.MainPage shows an empty navigation stack and a modal navigation stack with 1 page. this call PrismApplicationBase MyPRISMApp = (PrismApplicationBase)page.Parent; will return the nav stack that was used to navigate to the modal.

the question i have is who owns the nav stack that is returned from Application.Current.MainPage? because if i naviagate to a content page and that page is passed into GoBack() that call will return a page object with both nav stack only modal will be populated. how does the content page have a nav stack

billSpaulding commented 8 years ago

i get what you are saying and i would also have used that approach but what I'm seeing is that this code PrismApplicationBase MyPRISMApp = (PrismApplicationBase)page.Parent; Gets the page of interest without having to iterate and look for a match and deal with index, etc.

billSpaulding commented 8 years ago

you wrote: "Every one of those is possible and actually should be expected." sorry for any confusion but i was suggesting that they are all indeed true.

brianlagunas commented 8 years ago

page.Parent doesn't work like you think it does, and will not work reliably for other scenarios. Every page type can have a different navigation stack based on its parent and what views have been navigated to for a particular navigation branch. So that means that a content page can have a nav stack if its parent is a navigation page.

billSpaulding commented 8 years ago

ok that makes sense that the content page is essentially starting a new navigation root when navigated to from the parent. that's also what i observed with the two different sets of stacks...got it

but if Page.Parent doesn't work I'm wondering how you might go about getting a reference to the modals parent.

brianlagunas commented 8 years ago

A modal doesn't have a parent. It's modal :)

billSpaulding commented 8 years ago

sorry. not parent but the page that invoked the modal navigation!

at this point the method i shared earlier works on the scenarios below but i have seen others that it will not work on. at least not as is. Luckily i only need the below scenarios for the time being and to keep moving forward. thanks again for all the time you have given

NavigationService.Navigate("ViewA/ViewB"); NavigationService.Navigate("MyTabbedPage/MyNavigationPage/ViewA"); NavigationService.Navigate("MyMasterDetail/MyNavigationPage/ViewA");

billSpaulding commented 8 years ago

you wrote: "The first step should be finding the position of the current page in the proper stack. Then find the page prior to it in the stack. Then iterate over the prior pages modal and nav stack to find the proper page to call OnNavigatedTo"

I spent some time revisiting your suggestions. if you happen to have time to elaborate on the above statement please do. This is a low priority and you have already given plenty of time so no worries if I you have other items.

the part I need clairification on is

Bill

billSpaulding commented 8 years ago

to try to bring some clarity to the above questions if you have a nav flow like

MyMasterDetail>MyNavPage>ViewA>ModalViewB

the way I understand things is this will result in two different navigation stacks.

1- ModalViewB will contain a modal stack with a count of 1 and a nav stack with a count of 0 2- ViewA will contain a nav stack with a count of 1 and a modal count of 0

ViewA is the current page on the previous nav stack prior to navigating to ModalViewB. Now when you say we need to use the index position it would seem that would only be for an edge case in which I navigated backwards on the stack WITHOUT popping any pages and THEN called navigate(modal = true) otherwise how would the page that we need to invoke OnNavigatedTo on be any page other than the current page of the navigation stack that initiated the modal navigation

billSpaulding commented 8 years ago

oh boy :-) please disregard all of these questions! I set a break point at every method in the pageNavigationClass and It didn't take long to see how drastically I underestimated the complexity.

I think much of the complexity is due to trying to bring a unified approach to what really is two different concepts XFs nav stack and navmodal stack but if you can figure it out hats off to you!

couple of last thoughts. saying these with the understanding that I don't know the rest of the PRISM source to determine if they would cause issues in other directions.. just have a few diffent ways of thinking about the problem.

I noticed you have some pluralsight courses on PRISM going to check them out. thanks again I wish I could have been of more help!

brianlagunas commented 8 years ago

Yeah, its a doozy for sure. I have some ideas I will play with after my vacation. This discussion did help me through my thought process, so thanks for that. XF definitely made some interesting decisions regarding navigation, bit then again they are trying to unify nav for 5 or more different platforms in a single API.

brianlagunas commented 8 years ago

I just checked in some navigation improvements with the GoBack method call. Be sure to test it out.

kodejack commented 7 years ago

Hi Brian,

Loving using Prism with Xamarin, we are building around 50 apps for a client using it. However we are hitting issues with the INavigationAware methods not getting called when pressing the Back Button in the Nav Bar.

The only difference is, for the moment, the INavigationAware methods don't get called when using the back button. I hope to fix that soon.

As above you mentioned you would be looking into this, is there any update on this issue?

We are able to work round some of the issues using OnAppearing in the Pages but not all.

Thanks Gordon

brianlagunas commented 7 years ago

Yes, there is a 6.3 preview on NuGet which has this built in. Read what's new here:

http://brianlagunas.com/prism-for-xamarin-forms-6-3-preview-with-improved-template-pack/

kodejack commented 7 years ago

Thanks for the speedy response we tested this and the view transition had already completed before INavigationAware method was called. We need to know earlier than that, looking at the notes confirm navigation maybe what we are looking for, I'll let you know if this resolves our issue.

LucioMSP commented 7 years ago

Hi,

I have a issue using Prism, because I want open a ContentPage that can be see everywhere of the App, so, I tried this:

App.cs

public void OnTapGestureRecognizerTapped(object sender, EventArgs e) { Device.BeginInvokeOnMainThread(async () => { await NavigationService.NavigateAsync("SystemDetailPage", useModalNavigation: true, animated: false); }); }

And on the SystemDetailPage.cs have this:

private void okClick() { ((DemoApp.App)App.Current).Close(); }

That return to the App.cs:

public async void Close() { await NavigationService.GoBackAsync(useModalNavigation:true ); }

All this did not works, do you know why? I just try close the new screen (SystemDetailPage)

brianlagunas commented 7 years ago

You don't close screens in Xamarin.Forms. You push and pop them off the navigation stack. I don't know what OnTapGestureRecognizerTapped is or how it is defined, but when using a modal navigation, you are essentially replacing the root of the application. As long as there is a page before the current modal page, GoBackAync will pop the current page off the stack.

brianlagunas commented 7 years ago

You need to call GoBack from the Page you are leaving. Not from the App.cs

lock[bot] commented 4 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.