How to dismiss modal navigation page using Prism NavigationService? - prism

In my root view model I call something like
await _navigationService.NavigateAsync(
"/NavigationPage/Page1of2",
useModalNavigation: true
);
Sure enough it loads both view models in a modal navigation just fine. In Page1of2ViewModel I do another
await _navigationService.NavigateAsync(
"Page2of2",
useModalNavigation: false
);
Which view model now should dismiss that modal and how?
Using GoBackAsync() or GoBackAsync(useModalNavigation: true) neither of the 3 view model seem to be able to dismiss the modal flow back to my root view model.

When you place a "/" in you are signifying an absolute navigation. This is resetting the navigation stack completely. It's the same as MainPage = new MyPage(). So there is no modal navigation occurring here. The only way to pop a page off the stack is to use the NavigationService.GoBackAsync, or use the built-in software/hardware buttons to go back.

Related

Different Types of Navigation in Xamarin Forms

What is the difference between these two Navigation paradigms in Xamarin.Forms?
await Navigation.PushModalAsync(new Dashboard());
await Navigation.PushModalAsync(new NavigationPage(new Dashboard()));
What is a Modal Page
Navigation.PushModalAsync will cause the new Xamarin.Forms.Page to appear Modally, meaning its animation will start from the bottom of the screen, covering the previous current page and it will not contain a back-button.
On iOS, a user will not be able to swipe-left to return to the previous page.
Android users are able to use the hardware back button to dismiss a modal page.
Modal pages are useful when you want the user to make a conscious decision to dismiss the page.
Example
When an iOS user is filling out a form and they swipe left to go back, does it save the form or discard the form? It is unclear to the user. To make the UX more intuitive, you should display the form modally
UI Differences
Using await Navigation.PushModalAsync(new Dashboard()); will display the Dashboard Page Modally, but the new Page will not have a NavigationBar.
Using await Navigation.PushModalAsync(new NavigationPage(new Dashboard())); will also display the Dashboard Page Modally, but the new Page will have a NavigationBar.
Sample App Source Code: https://github.com/brminnick/XamList
Edit
#AlessandroCaliaro and I had a good discussion in the comments of his answer, below:
It's important to note that Xamarin.Forms.INavigation uses two different stacks, ModalStack and NavigationStack. Navigation.PushModalAsync adds a Page to the ModalStack and Navigation.PushAsync adds a Page to the NavigationStack.
And to pop a Page from the ModalStack, you need to use Navigation.PopModalAsync(), whereas you would use Navigation.PopAsync() to remove a Page from the NavigationStack.
The first, push a page in a "modal" way (without navigation bar on the top)
the second... is an error because you try to add a navigationpage to a navigationstack, but I think it is not possible....

Xamarin Forms Prism Navigation from TabbedPage behaves as PushModelAsync or the navigation bar disappears

In Tabbed page sample given by Prism, I want to navigate from ViewA (first tab) to ViewD(not the next tab but next navigation page).
I don't understand why this removes the navigation bar on the top:
_navigationService.NavigateAsync(nameof(ViewD));
Like PushModelAsync instead of PushAsync. So that I loose the back button on the navigation tab which is not intended.
Am I missing something here?
The reason for this is that ViewA’s parent is not a NavigationPage, the result is that the Navigation Service assumes you want modal Navigation. You simply need to add useModalNavigation: false, this will make the Navigation Service push ViewD correctly inside the Navigation Page.

iOS8 UISplitViewController: How to switch to master view in compact width window?

My root view controller is an UISplitViewController, which has a UITableViewController as master view controller. On iPhone (compact width), it looks like a UINavigationController.
Tap a cell to show detail view controller
Tapping the trash button would delete the current note. My problem is how to go back to the master view after that? Since it's an UISplitViewController, it can't pop the current view controller as UINavigationController does.
I had a similar problem and finally found a solution. As I understand it, when in compact width, the detail navigation controller becomes a view controller of the master navigation controller. So all you have to do is:
Determine if only one view is present by checking the split view controller's collapsed property. If it isn't collapsed (e.g. on iPad), you're already showing the table view in addition to the detail view.
If it is collapsed (e.g. on iPhone) get a reference to the master navigation controller via the detail navigation controller and have it pop to its root view controller which, in this case the your table view controller.
This is the code I use in my detail view controller. In your case I think you just need to add this code to the button action in your detail view controller:
if splitViewController!.collapsed {
let detailNavController = parentViewController as UINavigationController!
let masterNavController = detailNavController.parentViewController as UINavigationController!
masterNavController.popToRootViewControllerAnimated(true)
}
Good luck!

Storyboards: A loop of Modal Segues?

I want to implement something using Storyboards, but I don't know the best way to accomplish it.
I don't want to use a Navigation Controller, since I don't want the navigation bar at the top.
I just want the ability to switch from one view controller to the next.
I have a Main Menu view controller, which will segue into other views, and those views might segue to other views... Now, lets say that the last view in the chain has a "Return To Menu" button: should I just segue from that button to the Menu view controller? Or should I somehow dismiss all of the previous view controllers?
I don't need iOS to hold a copy of the Main Menu view controller after the user taps out of it, but I can't seem to find a way to just load a new view controller and present it, instead of having a parent view display it "modally".
Would it cause a memory leak if I just create a loop of modal segues?
(for example: Main Menu --> VC1 --> VC2 --> Main Menu --> VC3 --> VC4 --> Main Menu...)
Any help will be much appreciated.
Thanks!
Each segue creates a new instance of the destination view controller, so having a segue back to the main menu is not a good idea.
You would be better off dismissing the presented view controller(s), but note that it is possible to use a navigation controller without showing the navigation bar - the navigation controller has a property, navigationBarHidden, which you can set to hide this.

Monotouch UIScrollView and ModalView question

In my program I have the main window in the background which has a smaller, UIScrollView on it. I have buttons on each page of the scroll view which I want to bring up a modal view that can be dissmissed. It works fine for the first page, however, when I click the button on the second page of the scroll view the modal view that is brought up is on top of the first page instead of the second and the second page is completely blank. When I close the modal view, the first page has been replaced with the second page and the second page is still left blank... The code I am using is:
MVC = new NewsModalViewController(this);
MVC.ModalTransitionStyle = UIModalTransitionStyle.CoverVertical;
MVC.ModalPresentationStyle = UIModalPresentationStyle.CurrentContext;
I've been trying to play around with the frames but having no luck...
Any insights?
Cheers
I would rewrite the subpages to fire an event that the parent view listens to. Then, display the modal from the parent view (you can actually create the modal in the child view and pass it up on the event). This eliminates any problems with the modal being applied to the wrong context.
There may be another explanation, but this is the method I've implemented on a couple applications and has served me well. It appears that modals are best displayed only from the highest level view in the stack.

Resources