As I continue my exploration into Xamarin Forms, I continue to really take aim at the Navigation piece of the framework. My previous post I talked about a proposed solution that involved reaching outside Forms and into native code (for Android specifically). I really wanted to get beyond this.
PushAsync – Pushes a new page onto the navigation stack, or replaces the current content with a new page if no Navigation stack is present (Windows Phone only). Without a NavigationPage this method will not work (throws an exception) on Android and iOS.
PopAsync – Pops the most recent page off the Navigation stack. Havent tested what this method does on Windows Phone without a Navigation Page.
PushModalAsync – Push a page into a modal context. This will create a new, independent, Navigation context within the application. The modal that is created can be dismissed with a hardware back button; there appears to no way to stop this functionality. On Android and Windows Phone there really is no difference, to the user, between this method and PushAsync, on iOS however you will see the traditional cover vertical animation
PopModalAsync – Pops the most recent Model context and returns to the most recent Navigation context.
InsertPageBefore – allows manipulation of the navigation stack and the insert of a page before another. Does not work on Windows Phone, complains about the new page being outside the navigation scope. Following usage, you will have to write code to actually get to this page.
RemovePage – removes a page from the Navigation stack. Does not work on Android
PopToRootAsync – pops to the first page in the Navigation stack. Used very commonly with InsertPageBefore to change the root page for an application.
By no means can I say that this is comprehensive, but its clear that not all of the methods work across the platforms. This leads to a need to injection “helpers” into the core from the platform specific to control the navigation. Here is an example that I have created within Score Predict
This is the Windows Phone version which shows using RemovePage to create a new root. This is because InsertPage does not appear to work on Windows Phone. Here is the Android version:
The ability to use InsertToPage makes this much simpler. Here you also see a very common pattern of using InsertPage to change the first page in the Navigation stack and then using PopToRootAsync to immediately go to that page.
You may find it weird that I am passing in INavigation to each of these methods. The reason for this is, I am calling them from a View Model. At present, I have not found a good way to inject the Navigation property into other classes. I am hoping a future release of Forms will give us more accessibility into how components like this are resolved.
For giggles, here is the iPhone version
You can see that it almost directly parallels the Android version in how it manipulates the Navigation stack.
I am pleased that I have removed the need to call platform specific code and instead I have found a way to use the Forms components to suffice for Navigation. However, I believe the aim of forms should be to support a single navigation flow that can be properly supported across all three platforms; that is not the case at the moment.