So you would like to override the Navigation Bar back button click event in your Xamarin Forms App? 😉 Yeah could be for a Sign up Page, Order Details Page, or any kind of a Page where you want to do some execution or confirmation before the user actually navigates back to the previous page in your app…
It’s BACKWARD navigation time…
Yes we are not talking about forward navigation here, but BACKWARD navigation! where the user clicks on the back button on the Navigation Bar, or the actual Back button in Android phones, where we need to have some validation before the user actually navigates…
Oh hello! Where do you think you’re going? Are you sure you want to go back?
Do you want to save your changes before you go back?
Please complete the empty fields because you go back!
Do you want to go back before you save your changes?
Please confirm you want to cancel your changes and go back…
Well you know the scenarios… 😉
ummhh… but in Xamarin Forms?
Yeah the question is can we actually implement this behavior in Xamarin Forms?
YES! you can, but…
well yes obviously you can override the OnBackPressed() method in ContentPage control, but…
it works only on Android and only for the physical back button…
not the Navigation Bar back button…
Yes fellas, if you want to achieve the above behavior in Xamarin Forms, you literally can not do it straight out of the box, because the override-able OnBackPressed() method in ContentPage only gets fired on Android’s physical (or screen bottom) back button’s click. It does not work for the Navigation Bar’s back button click.
But I did it…
So here’s a sneak preview of the results of my implementation…
Now look at that awesomeness.. When the user clicks on the Navigation Bar’s back button, I’m popping up a confirmation dialog.. 🙂
Alright, how did I do this?
So in order to do this we need to drill down to the native level and handle these Navigation Bar back button click. Let me explain further….
So after compilation the Navigation Bar that we call in Xamarin Forms, turns into the Action Bar for Android during run time. So in order to capture the back button click the Action Bar we need to override the OnOptionsItemSelected() in your MainActivity class, which allows us to capture the navigation bar’s back button click. Since Xamarin Forms runs on a single Activity overriding the above event on your parent Activity class is enough to get our job done. 😉
And for iOS , the Xamarin Forms’s Navigation Bar is mapped to the UINavigationBar in iOS run time. But unfortunately there’s no way to override the back button click on the default back button in the UINavigationBar, the only solution is to replace the default back button with a custom back button and do our necessary event subscriptions with it. We can replace the default back button with our custom back button at the ViewWillAppear() event call of the UIViewController, and set our custom back button to UILeftBarButtonItem property. 😀
Bridging between Native Xamarin and Xamarin Forms?
Yep just by native implementation is not enough since we need to get a call back to our Xamrin Forms PCL or Shared project level right? So for that we shall be using a simple Action event where we subscribe to in our Xamarin Forms code level, and do the necessary execution when the mentioned Action event gets fired from the native project levels. 😉
Simple as that! 😀
Alright! time for coding.. 😀
So first we need to create a Custom ContentPage to be used as our Page in our Xamarin Forms project, where as we could enable or disable the Nav bar Back button event overriding. And we shall name it as the “CoolContentPage” lol, well why not, it is indeed cool! 😉 lol
So there we have created the Action event that we are going to subscribe to in our Xamarin Forms code level and to be invoked from Xamarin native project level.
You can also see that I’m using a bool property to enable or disable the overriding of the Back Button click event, so that we can decide whether to subscribe to the overriding event or not as a page property.
next Xamarin Android stuff…
So as I explained at the beginning we need to override the OnOptionsItemSelected() event in our MainActivity class in order to capture the nav bar back button click in Android for Xamarin Forms.
phewww… that was some long code snippet yeah! fear not child! let me explain…
So as I mentioned before when the user clicks on anything on the default Android navigation bar the above OnOptionsItemSelected() gets fired, where as we will check the clicked item’s id and check for the back button’s default id. Yes the default back button id is the same 16908332 integer in Xamarin Forms – Android applications.
There we will get an instance of the current Xamarin Forms page in the Navigation stack and look if the page has been subscribed to the Custom Back button click event, if so there we will invoke our CustomBackButtonAction, and disable the default click event. If the page hasn’t subscribed to the Action, then we shall pass the click event to the base allowing the default back stack navigation. 🙂 Simple as that! 😀
Now you may see that I have also overridden the OnBackPressed event as well. This is really not necessary if you don’t want to but as a good practice it’s better to override both Nav bar back button and physical back button click events at the same time.
then Xamarin iOS stuff…
Here comes the iOS implementation where we are going to replace the custom Navigation Bar back button and use our own Custom button for the back button as I explained at the beginning. 😀
Now I know when we are to replace the Back button of iOS, we need to replace it with the same similar looking back button, although its custom. This is not really an easy task, because we need to construct the identical back button from the scratch, including the image, fonts and inset values and so on. I have written a complete blog post about this in one of my previous posts. If you want you could refer to it as for the complete explanation here : Creating an identical Custom Navigation Bar Back Button in Xamarin iOS…
But for the sake of this post, I shall post the whole implementation here, but I shall not drill down to detailed explanation. 🙂 You can always prefer to the original post up there.. 😉
Now keep in mind for iOS you need to override the ViewWillAppear() method in your CoolContentPageRenderer class.
So the below code should be placed inside your CoolContentPageRenderer class…
Alright there you have it, now keep in mind you need to attach the iosbackarrow.png image to your Xamarin Forms solution’s iOS project’s Resources folder. 😉
As I mentioned above I will not be getting down to the details of the above implementation, but I will explain the nuts and bolts related to this post.
So if you notice above we are creating a custom button and we are subscribing to the TouchDown event of it, which is where we are going to check if the current page has subscribed to the CustomBackButtonAction event or not and proceed with the custom action or default back stack navigation event… 😀
Simple as that! 😉
How to use it, you asked?
Alright let’s consume this beautiful implementation! 😉
So here I’m using our CoolContentPage as a XAML page in my Xamarin Forms solution.
You can notice that I’m setting the EnableBackButtonOverride=”True” property for enabling the overriding of the nav bar custom back button click.
So here’s in the code behind we are subscribing to the CustomBackButtonAction with our Alert dialog asking a verification if the user is sure that they want to go back.
Pay good attention here where if the user confirms they want to go back, then we will manually Pop the page by calling Navigation.PopAsync() method. If not the back button click event will be ignored thanks to our custom back button click event overriding implementation. 😀
Now keep in mind, subscribing to the Action can be done in many other different ways, code-behind may not be the best practice if you’re heavy MVVM minded, where as may be you could move the custom Action event subscription to the CoolContentPage’s OnAppearing event or base class. All up to your preferences… 😉
Alright, let’s fire it up!
Oh child, just hit that F5! 😉
Look at that beauty! 😀 Well the colors and stylings I added myself though.. 😉
So you may grab the code up in my Github: Xamarin-Playground/XFNavBarBackBtnClickOverride
There you go fellas!
Happy coding and share the love! 😀
Udara Alwis out!