Friday 23 January 2015

Xamarin Forms Navigation–Dealing with Login

This is the third in a series of posts on Xamarin Forms – in this instalment I want to add login capability to my app, but this isn’t as simple as I thought it would be. I’m used to crafting interfaces with XAML in WPF and Silverlight, and have been doing so for several years now, but with Xamarin Forms things are a little different.

Here’s what I want to be able to do, courtesy of Visio…

image

When the app starts up I’ll check if the user has a valid token, and if so skip the login part and go straight to the main page.

If however the user hasn’t yet logged in I want to show a “carousel” where I can do some app advertising, then let them choose from one of the login providers I’ve integrated, and once logged in show the main form. The gnarly part here is the navigation support – once at the MainForm stage I don’t want to allow the user to “back out” into the login part, and so far on the intertubes I’ve not seen a clear way of doing this so looked into this myself.

I’m using Xamarin Forms 1.3 which has improved navigation support, so the first thing I tried was a main form that cleared out the navigation stack when it showed up. This worked to a fashion, in that the back-stack was cleared, but it left a “< Back” button on the navigation section when I arrived at the main form, and that was less than ideal.

After trying some other options (non of which panned out) I went back to first principles and looked at how the application startup sequence worked, and from that arrived at a simple solution – at the point where I need to display the main page, I simply call the following…

    var nav = new NavigationPage(new MainPage());
nav.BarBackgroundColor = Color.FromHex("#195174");
nav.BarTextColor = Color.White;

Application.Current.MainPage = nav;

And boom - the main page is shown and there's no previous pages that can be navigated to.

I’d originally created my main page and set that as the root, then coded the login forms as modal, and whilst that worked OK it had the undesired behaviour of showing the main form first (briefly), then navigating to the login page. That wasn’t particularly great as I want login to be the first thing seen when the application is run for the first time.

The downside of my approach here is that there’s no transition between the last login page and the main form, I haven’t found a way to do that at the moment.

I’m not sure if this is the best method either – however there doesn’t seem to be (or I cannot find) any alternatives that work quite how I want them to. I want to be able to use navigation during login, as I have a carousel page and then a provider selection page (and maybe more pages after that, once I’ve written them!), so using a Modal login page doesn’t suit my purposes.


Demo Code


If you would like to grab my example project please download it here. The structure is deliberately simple (I usually use Autofac and XAML in my projects, this has neither as there’s less to setup). When you run the app you’re on the carousel view which consists of three pages…


IMG_1304    IMG_1305    IMG_1306


I’m using a carousel here and a timer to move between the images, you can swipe too should you wish to. When you click on the “Providers” button a new page is shown, where you would ask the user to choose their login provider. I’ve cheated and just shown a login button…


IMG_1307


When the Login button is clicked I construct a new navigation page and the main page within it, and then set the application root page to this combination using the code shown above which gives the main page shown below.


IMG_1308




You can navigate elsewhere using the button…


IMG_1309  IMG_1310


And you can navigate directly back to the root page when you’re on the “At the end” page.


Conclusion


In this example I’ve attempted to show how you can “break out” of the navigation hierarchy and start a new navigation stack. There may be a better way to do this and if so please let me know!

177 comments: