Category Archives: Coding

XFHACKS-003 Editor with a Border!

Ever wanted to have a Border around your Xamarin.Forms.Editor control? Welcome to another lightening short post of me hacking around Xamarin.Forms elements!

Sneak Peak!

That’s what we gonna be build yol!

XFHACKS Recipe!

The default Xamarin.Forms.Editor control is a very dull and simple control which doesn’t have much of customization properties of its own. In this case the Editor doesn’t even have a proper border around it that explicitly shows the edge of the element. So here we’re going to look into how to add a nice Border around Editor in Xamarin.Forms without any custom renderers or 3rd party libraries!

We all know the Frame control, which has a nice Border property, and also CornerRadius property allowing us to control the curves of the corner edges of it. This is the simple magic we’re going to use here. We’re going to wrap our Editor inside this Frame control. 😀

How simple and easy is that eh!

Code!

Behold the golden XAML code!

<!--  Editor with a Border Control  -->
<Frame
	Padding="5"
	CornerRadius="8"
	HasShadow="True"
	OutlineColor="#2196F3">
	<Editor BackgroundColor="Transparent" TextColor="Black" />
</Frame>

 

So there we go as we discussed the Frame is wrapping around the Editor control. So the Frame has been configured with CornerRadius property so we can have some nice round corners. Then the Padding has been reduced to 5 so we have less space between the border and the Editor view, this you may change as you wish. 😉

HasShadow property is something you could change as you wish, which you should keep in mind, behaves differently on iOS and Android.

Now just to add something extra, imagine if you wanted to have the whole background with a certain color for the given Editor, this is how simple it is!

<!--  Editor with a Border Control  -->
<Frame
	Grid.Row="4"
	Padding="5"
	BackgroundColor="#7fc5ff"
	CornerRadius="8"
	HasShadow="False">
	<Editor BackgroundColor="Transparent" TextColor="Black" />
</Frame>

 

We simply add the BackgroundColor property of the Frame and then you set the HasShadow to false so it doesn’t show up Border Color just for the kicks of it. 😀 So just like that you could easily customize this as you wish!

 Important: You could also move that whole piece of XAML to a separate XAML file, so that you could set it up as a reusable Control in your project! 😉

Fire it up!

There you have it running on Android and iOS like a charm!

Let me type something inside our “cool” Editor…

 

Grab it on Github!

https://github.com/UdaraAlwis/XFHacks

Well then, that’s it for now. More awesome stuff on the way!

Cheers! 😀 share the love!

Advertisements

XFHACKS-001 Picker with an Icon!

Ever wanted to have an Icon element attached to a Xamarin.Forms.Picker control? Then you’re at the right place. Welcome to another lightening short post of me hacking around Xamarin.Forms elements!

Sneak Peak!

That’s what we gonna be build yol!

XFHACKS Recipe!

Usually you would think you need to implement a Custom Renderer to get this done or use a third party control! I say NO! NO! NO!

You can easily do this right from Xamarin.Forms without any native coding or 3rd party library, let me explain.

In a Xamarin.Forms Grid layout we could place Elements on top of each other, using this simple advantage, we’re going to place an Image as an icon under a Picker control, and of course we’ll be setting the Background color of the Picker to Transparent! 😉 Simple right?!

Code!

Behold the golden XAML code!

<!--  Picker with an Icon Control  -->
<Grid
     Grid.Row="1"
     HorizontalOptions="Center"
     WidthRequest="200">

     <!--  Icon Image  -->
     <Image
          Grid.Column="1"
          HeightRequest="25"
          HorizontalOptions="End"
          Source="{local:ImageResource XFHacks.Resources.dropdownicon.png}"
          VerticalOptions="Center"
          WidthRequest="25" />

     <!--  Picker Control  -->
     <Picker
          Title="Select a Monkey"
          Grid.Column="0"
          Grid.ColumnSpan="2"
          BackgroundColor="Transparent">
          <Picker.ItemsSource>
               <x:Array Type="{x:Type x:String}">
                    <x:String>Baboon</x:String>
                    <x:String>Capuchin Monkey</x:String>
                    <x:String>Blue Monkey</x:String>
                    <x:String>Squirrel Monkey</x:String>
                    <x:String>Golden Lion Tamarin</x:String>
                    <x:String>Howler Monkey</x:String>
                    <x:String>Japanese Macaque</x:String>
               </x:Array>
          </Picker.ItemsSource>
     </Picker>

     <Grid.RowDefinitions>
          <RowDefinition>
               <RowDefinition.Height>
                    <OnPlatform x:TypeArguments="GridLength">
                         <On Platform="Android" Value="50" />
                         <On Platform="iOS" Value="35" />
                    </OnPlatform>
               </RowDefinition.Height>
          </RowDefinition>
     </Grid.RowDefinitions>
     <Grid.ColumnDefinitions>
          <ColumnDefinition Width="*" />
          <ColumnDefinition Width="25" />
     </Grid.ColumnDefinitions>
</Grid>

 

There you have it just like we discussed in the recipe, we have placed our Picker control on top of the Image control, and we’re using a Grid to bring all of this together. If you look closely, we are using two columns, the Picker is spread across both columns, and the Icon Image is only added to the last column, with a fixed width of 25 units, thereby aligning the Icon to the right most corner of the Picker from underneath it. 😀

You can set the WidthRequest to whatever the value you prefer. And as of Platform specific values we’re setting the Grid Height accordingly to the best appearance of Android and iOS separately, you’re in full liberty to change them as you wish. 

Important: You could also move that whole piece of XAML to a separate XAML file, so that you could set it up as a reusable Control in your project! 😉

Pretty straight forward eh!

Fire it up!

 

There you have it running on Android and iOS!

Grab it on Github!

https://github.com/UdaraAlwis/XFHacks

Well then, that’s it for now. More awesome stuff on the way!

Cheers! 😀 share the love!

Welcome to XFHACKS Series!

Hello humans, welcome to my XFHACKS series, where I share my experience on hacking around the Xamarin.Forms environment and pushing the limits of it to get sh*t done, in all kinds of unexpected and creative ways! 😀

Specially I’m going to share my experience on implementing beautiful UI elements right from Xamarin.Forms, without any native implementations. The majority misconception is that in order to implement complex or highly customized UI elements with Xamarin.Forms, you often need to use a third party library or create custom renderers and do native customization, every single time!

I’m here to prove them wrong! There’s so many ways to implement complex and beautiful UI elements right from Xamarin.Forms out of the box without the need of any native renderers or third party libraries! 😀

Stay tuned fellas! Awesome stuff on the way!

Although I’m thinking of renaming the series name to HACKXAMFORMS though instead of XFHACKS!

Meh! I’ll think about it later! 😛

Cool Animating Dots Control from Xamarin.Forms Animations!

Three dots, blinking and pulsating sequentially made with pure Xamarin.Forms Animations! (no third party elements, heck not even any images used)

A little fun experimental-implementation I did a while back, actually based on something I did long time ago for an office project, but then figured out I could make it much better in a later time, so thought of working on it and putting it out there.

So basically we needed to have a Loading screen or Activity indicator screen with cool three dots animating sequentially, instead of using a GIF, I wanted to do this purely from Xamarin.Forms without any use of a 3rd party component, not even any image or icon.

Yes, I ended up hacking my way to get this done!

Here’s that interesting journey unfolding…

Xamarin.Forms.Animations is awesome!

This is something I need to get out of my chest. No one would actual believe this, but there’s so many awesome stuff you could do with the built in Animations of Xamarin.Forms right out of the box.

Surprisingly it’s super simple as well!

Sneak Peak!

So here’s what I’ve built and what you’re gonna get! 😉

TADAAA! pretty cool eh!

Let’s get started…

So before I get started, the requirement here is to build a reusable “Control” that we can embed into a ContentPage that we would be using as a “Loading Screen” or an Activity Indicator screen as some might call it. So this is going to be a separate reusable View which you can embed anywhere you want to and use it right away, which will be independent of it own, yes even the whole Animation sequence is self sustained by itself. 😉 Oh yeah! Cool stuff ahead! 😀

Building the UI..

First of all let’s go on create a ContentView control, let’s name it, AnimatingDotsControl!

What we need here is just simple “three dots”, but like I said in the beginning I don’t want to use any third party components or even external Image to emulate “a dot” element.

So what am I going to use for “a dot”? Xamarin.Forms.Frame! MIND BLOWN!

Let the Hack-be-unfolded!

Right on fellas, just another Xamarin.Forms hack of my own, Frame View has this awesome property called CornerRadius, which we are going to use for our advantage here, when its sufficiently set properly to the proportion of the width and height of it, voila! you render a circle or a dot in this case.

So let’s go on add three Frame elements horizontally inside a Grid view. And also to emulate the blinking, “on” and “off” state of a dot, we need to maintain two Frame elements to represent one dot each. We’re going stack them on top of each other, so when the first one goes to off state the second one in the background will come to visibility and emulate the off state. So for the ease of use let’s call our tiny little Frame elements, Dot1, Dot2 and Dot3 and lay them out nicely as we discussed.

<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
    x:Class="XFAnimatingDotsControl.AnimatingDotsControl"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
    <ContentView.Resources>
        <ResourceDictionary>
            <Style x:Key="AnimatingDotsStyle" TargetType="Frame">
                <Setter Property="Padding" Value="5" />
                <Setter Property="BackgroundColor" Value="White" />
                <Setter Property="CornerRadius" Value="6" />
                <Setter Property="HasShadow" Value="False" />
                <Setter Property="HorizontalOptions" Value="Center" />
                <Setter Property="VerticalOptions" Value="Center" />
                <Setter Property="HeightRequest" Value="4" />
                <Setter Property="WidthRequest" Value="4" />
            </Style>

            <Style
                x:Key="BackgroundDotsStyle"
                BasedOn="{StaticResource AnimatingDotsStyle}"
                TargetType="Frame">
                <Setter Property="BackgroundColor" Value="DimGray" />
            </Style>
        </ResourceDictionary>
    </ContentView.Resources>
    <ContentView.Content>
        <Grid ColumnSpacing="2" HorizontalOptions="Center">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="25" />
                <ColumnDefinition Width="25" />
                <ColumnDefinition Width="25" />
            </Grid.ColumnDefinitions>

            <!--  Background Dots  -->
            <Frame Grid.Column="0" Style="{StaticResource BackgroundDotsStyle}" />
            <Frame Grid.Column="1" Style="{StaticResource BackgroundDotsStyle}" />
            <Frame Grid.Column="2" Style="{StaticResource BackgroundDotsStyle}" />

            <!--  Animating Dots  -->
            <Frame
                x:Name="Dot1"
                Grid.Column="0"
                Style="{StaticResource AnimatingDotsStyle}" />
            <Frame
                x:Name="Dot2"
                Grid.Column="1"
                Style="{StaticResource AnimatingDotsStyle}" />
            <Frame
                x:Name="Dot3"
                Grid.Column="2"
                Style="{StaticResource AnimatingDotsStyle}" />
        </Grid>
    </ContentView.Content>
</ContentView>

 

There you go. Just like we discussed we have our UI set up in a reusable ContentView control, just like we discussed above. Oh and don’t be worried by the use of Styles, I just like to make my XAML look neat and clean. 😉

Building the Animation!

Here’s the golden part of the whole post, the actual Animation magic brewed purely with Xamarin.Forms! Most people are aware only of the Xamarin.Forms Animation Extension methods, the typical FadeTo(), ScaleTo(), etc whatnot. But that’s just the tip of the ice berg I tell you! 😀

Here’s a little heads up if you’re not aware: Xamarin.Forms.Animation!
The whole Xamarin.Forms.Animation class itself has many more awesomeness possibilities, it allows us to create our own Animation sequences. Oh yeah! how cool is that eh!

These custom Animation objects can be attached to any Xamain.Forms.View and make them dance like whatever the ways we want, as in to animate any of its properties as we wish. They can sequentially change value of any property for any given period of time, even repeatedly. That is the whole bread and butter of this implementation. The Animation object constructor allows us to execute a sequential loop of an action with any given value, incremented or decremented, with the Easing properties, and finishing it with another action. Let’s use this for our advantage…

new Animation(alpha => Dot1.Opacity = alpha, 1, 0, Easing.CubicOut, () => Dot1.FadeTo(1))

 

So we’re going to using the Opacity property of our Frame view, and change its value from 1 to 0 in a loop, with an CubitOut Easing behavior, and reversing it back in the end of the execution, thus creating the blinking effect! 😀

And here’s the coolest part, you can actually attach an Animation object into another Animation object, and so on, so that you can execute a bunch animations sequentially across multiple views. Animation.Add() method gives you this awesomeness, where as you can define a starting point of the timeline and ending point for that specific animation object, in the whole animation sequence. So given our three animating elements, let’s break our timeline into 3 time chunks, giving each element a time span of 0.33 milliseconds.

var pulseAnimation1 = new Animation();

pulseAnimation1.Add(0, 0.33, new Animation(alpha => Dot1.Opacity = alpha, 1, 0, Easing.CubicOut, () => Dot1.FadeTo(1)));

 

So using that we’re going to animate three of our “dot views”, Dot1, Dot2 and Dot3, by attaching their own animation objects to a single Animation. We’re going to repeat the same above Add() call to Dot2 and Dot3 in the next step.

Before I get into the full animation code, the way we actually run this animation sequence is by calling the Animation.Commit() method, passing the parent View and some useful bits we could use to customize the animation sequence altogether.

private void RunAnimations()
{
	var pulseAnimation1 = new Animation();

	pulseAnimation1.Add(0, 0.33, new Animation(alpha => Dot1.Opacity = alpha, 1, 0, Easing.CubicOut, () => Dot1.FadeTo(1)));
	pulseAnimation1.Add(0.33, 0.66, new Animation(alpha => Dot2.Opacity = alpha, 1, 0, Easing.CubicOut, () => Dot2.FadeTo(1)));
	pulseAnimation1.Add(0.66, 0.99, new Animation(alpha => Dot3.Opacity = alpha, 1, 0, Easing.CubicOut, () => Dot3.FadeTo(1)));
	
	pulseAnimation1.Commit(this, 
		"loadingIndicatorPulseAnimation",
				10, 1100, null, null, () => true);            
}

 

So you can see how we have allocated each animation chunk 0.33 milliseconds and most importantly at the end the Commit() call, passing in the current view we’re attaching this animation to, the time in milliseconds between frames, the allocated time in milliseconds  for the whole animation sequence, and the null for easing and finishing action, since I’ve already defined them in the child animations themselves, and the last parameter, enabling the repeating functionality. So the animation will keep running forever as long as its active.

Now we have a self sustaining animation that runs repeatedly, but what if we want to stop it and discard it, in the case of the disposing or removing the View? that’s where AbortAnimation() call comes in.

// abort the animation on element disposing
this.AbortAnimation("loadingIndicatorPulseAnimation");

 

Remember we gave a little name to our animation? yeah that’s what we’re going to use and such a simple call the animation will stop and discard itself.

A true self sustaining Animation Control!

Alright! So now we have our full Animation implemented, the next thing we need to do is to make sure its self sustaining, since we’re going to use it inside an independent control.

So whenever the Control is attached to the UI or made visible, we need to make sure to start the Animation and when the Control is removed from UI or disposed, then we should stop the animation and dispose itself.

In order to do this we need to look into the life cycle of a Xamarin.Forms.View!

Let the Hack-be-unfolded!

So this is a little hacking around I came up with myself after overriding a bunch of methods and debugging the run time of Xamarin.Forms, where as when any given View gets attached to a parent or becomes visible, there’s an internal property that gets fired, which is called “Renderer”, even at the time of View goes out of visibility or removed from parent, the same property will get fired. I’m presuming this to a call to the native renderer of the View itself back and forth at runtime. I’m going to use this as Entry and Exit points for managing our Animation.

We shall override the OnPropertyChanged event of our ContentView and watch out for the “Renderer” property change, maintain a little flag to mark down our Animation started and ended state.

public partial class AnimatingDotsControl : ContentView
{
     public AnimatingDotsControl()
     {
          InitializeComponent();
     }

     private bool _animationStarted;
     
     protected override void 
          OnPropertyChanged(
               [CallerMemberName] string propertyName = null)
     {
          base.OnPropertyChanged(propertyName);

          if (propertyName == "Renderer")
          {
               if (!_animationStarted)
               {
                    // start the animation on element rendering
                    _animationStarted = true;

                    RunAnimations();
               }
               else
               {
                    // abort the animation on element disposing
                    this.AbortAnimation(
                            "loadingIndicatorPulseAnimation");
               }
          }
     }

     private void RunAnimations()
     {
          ...    
     }
}

 

There you go, now we have a fully self sustaining animation which will start on its own when the Control is attached to a parent or made visible, and then dispose itself when the Control is removed from parent or made out of visibility! 😀

Let’s consume it!

No more waiting, let’s consume this bad boy!

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="XFAnimatingDotsControl.LoadingScreen"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:xfAnimatingDotsControl="clr-namespace:XFAnimatingDotsControl;assembly=XFAnimatingDotsControl"
    BackgroundColor="Gray">

    <Frame
        BackgroundColor="Transparent"
        HasShadow="False"
        HorizontalOptions="Center"
        OutlineColor="Transparent"
        VerticalOptions="Center">
        <StackLayout
           BackgroundColor="Transparent"
           Orientation="Vertical">
            <Label
                FontAttributes="Bold"
                FontSize="23"
                HorizontalOptions="Center"
                HorizontalTextAlignment="Center"
                Text="Loading"
                TextColor="White" />
            <!--  Embedding our Animating Dots Control  -->
            <xfAnimatingDotsControl:
                 AnimatingDotsControl HorizontalOptions="Center" />
        </StackLayout>
    </Frame>

</ContentPage>

 

There we have embeded our own AnimatingDotsControl into a ContentPage that we would be using as a “Loading Screen” or an Activity Indicator screen as some might call it. Then you could use that page as a Modal Page and make it visible or discard whenever you wish so. 😉

You can attach our little awesome Animation dots control anywhere as you wish and it will work out nicely like a charm, while behaving and maintaining itself.

 

That’s our bad boy in action on iOS and Android! 😀

Github it if yo lazy!

So all of this is hosted on my git repo: https://github.com/XFAnimatingDotsControl

Feel free to grab your copy if you’re too lazy to DIY! 😛

Imagination and creativity is your weapon against the odds, keep on pushing the limits and hacking your way through my fellow developer! That’s what makes us the “Developers”, we build cool stuff yol!

That’s it for today.

Cheers all! 😀 Share the love!

Advanced Prism Tab Navigation with MVVM & Test friendly manner in Xamarin.Forms!

If you’re looking for how to navigate inside a Xamarin.Forms Tab Page programatically in a MVVM friendly and Test-able manner, without having any XAML-Code-Behind garbage. Welcome to my post!

Keep in mind, since this is an advanced topic, there’s not going to be any step by step intro’s to Prism or MVVM or whatnot ;)!

Sneak Peak!

Here’s a little sneak peak of the outcome of it.

PERKS:

  • Switch between Child-Tabs when you are,
    • Coming into the TabbedPage
    • Already in the TabbedPage
    • Coming back to the TabbedPage
  • Fully MVVM compatible
  • Fully Test-able, yaay!
  • Binding, Commands and Interfaces FTW!
  • Almost no XAML-code-behind garbage
  • Coming back to the TabbedPage, the Child-Tab switching occurs only when the TabbedPage is actually visible

How cool is that eh! 😉

 

Woot! Let’s get started then…

My MVVM addiction…

You know me, I’m all about that MVVM & Test-able Software Architecture life forever yol! xD

Being hustling with one of the best dot net application craftsman, has made a massive impact on my perspective of software engineering, rather than just writing some code, putting some shit together and make it work. I’m extremely obsessed with architecture of any given application I develop now, long last extendability, and fully test driven approach. High quality, clean code with all of dot net standards and complete separation of Views and ViewModels.

Backstory…

So recently, I was working on this Xamarin.Forms application which was using Prism as the MVVM framework with a fully test driven architecture. There we had all of our Views and ViewModels separately implemented with a clean architecture, whereas we didn’t have a single line of extra XAML-code-behind garbage. 😛

So the requirement was to implement a TabbedPage and which should be able to switch between its Child-Tabs programatically at runtime, to be more specific, we should be able switch the selected Child-Tab when the user is:

  • Coming into the TabbedPage
  • Already in the TabbedPage
  • Coming back to the TabbedPage after navigating forward.

And the most interesting part was this we had to handle this in a fully MVVM and Testable manner. 😮

Now this would have been much easier, if you had taken out the whole MVVM and Test-first aspect out of the equation, with some dirty XAML-code-behind garbage you can easily handle this. But in this situation, I was backed against the wall, How on earth could anyone achieve this?

but as usual, I figured it out!

The Recipe time…

So here’s how I implemented it, in conclusion we’re going to use an Interface that will allow us to bridge the View-ViewModel separation and a Bindable property inside the TabbedPage, that will react to the changes of the ViewModel’s “SelectedTab” property.

That interface is going to be implemented into the ViewModel. Then through the ViewModel we’re going to register that whole instance in our IoC container, when the user navigates into the TabbedPage. The bindable-property of the TabbedPage will be bound to the property in ViewModel. 😀

Which will allow us to access the interface instance from the IoC container from anywhere in our code and change the Selected Child-Tab.

Oh also I forgot to mention that with Prism, by default we can set the selected Tab-Child when we ‘first navigate into the Tab Page’, so handling that scenario is going to be a no-brainer, thus I will not focus on it in this post.

We shall work on navigating inside the TabbedPage when we’re already inside it, and when we’re coming back to the TabbedPage from another page after navigating forward. Which is going to be a piece of cake with our interface implementation approach.

Just to add something extra, we will maintain a flag property inside the TabbedPage, to make sure to allow the Selected Child-Tab switching happens only when the TabbedPage is visible to the user. Just to make it look nicer!

Since all of this is a simple combination of Bindable-Properties, Interfaces and Commands, this whole implementation is fully test-able. Yeah fine, I’ll show you how to write some tests for it as well! 😛

Sounds pretty straight forward eh! 😀 time for coding! 😉

Implementation time…

So just a heads up, my project configuration is as follows.

I’m using a Xamarin.Forms project (dot net Standard 2.0) created with Prism Templates for Visual Studio. And the IoC container is the default Unity container comes with Prism.Forms setup. As of the Tests I’m using a xUnit Dot net project, which I will get into details later.

So before you begin make sure you have the above setting in place.

1. interface to save the day…

First, the simple Interface which is going to save the day like we discussed above…

public interface IMyTabbedPageSelectedTab
{
	int SelectedTab { get; set; }

	void SetSelectedTab(int tabIndex);
}

 

There we have a SelectedTab property, and a separate setter method for it, just in case for backup scenario. If you don’t need both then stick to one of them. 😀

2. the TabbedPage…

Alright then let’s get started with our TabbedPage implementation, let’s call it MyTabbedPage.

<TabbedPage
    x:Class="AdvPrismTabNavigation.Views.MyTabbedPage"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:AdvPrismTabNavigation.Views;assembly=AdvPrismTabNavigation"
    xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
    Title="{Binding Title}"
    prism:ViewModelLocator.AutowireViewModel="True"
    SelectedTabIndex="{Binding SelectedTab}">
    <TabbedPage.Children>
        <local:TabChild1Page />
        <local:TabChild2Page />
        <local:TabChild3Page />
    </TabbedPage.Children>
</TabbedPage>

 

There’s the XAML code for our MyTabbedPage, notice how we’re binding the SelectedTabIndex property to the ViewModel’s property which I’ll show later in this post. Meanwhile let’s have add some child pages to our MyTabbedPage as well.

Alright next take a look at the MyTabbedPage‘s code behind stuff, which is very minimal.

public partial class MyTabbedPage : TabbedPage
{
	private bool _isTabPageVisible;

	...
        // SelectedTabIndex 
	// bindable property goes here...
	...

	public MyTabbedPage()
	{
		InitializeComponent();
	}
	
	protected override void OnAppearing()
	{
		base.OnAppearing();

		// the tabbed page is now visible...
		_isTabPageVisible = true;

		// go ahead and update the Selected Child-Tab page..
		this.CurrentPage = this.Children[SelectedTabIndex];
	}

	protected override void OnDisappearing()
	{
		base.OnDisappearing();

		// the Tabbed Page is not visible anymore...
		_isTabPageVisible = false;
	}

	protected override void OnCurrentPageChanged()
	{
		base.OnCurrentPageChanged();

		// when the user manually changes the Tab,
		// we need to update it back to the ViewModel...
		SelectedTabIndex
			= this.Children.IndexOf(this.CurrentPage);
	}
}

 

As I mentioned in the recipe, there’s the flag _isTabPageVisible, we’re going to use to keep track of the Visibility of the TabbedPage. There when we’re coming back to the TabbedPage from a backward navigation, we’re executing the selected Child-Tab according to the SelectedTabIndex bindable property.

Important Note: You can even make the above little chunks of code go away from the XAML-Code-behind, by using triggers and attached properties, which I’m not going to get into here, to maintain the simplicity of the implementation. Come on, use your own creativity people! 😉

Next we’re creating the Bindable Property inside the TabbedPage which will handle the View-ViewModel communication. Let’s call it SelectedTabIndex property.

public static readonly BindableProperty SelectedTabIndexProperty =
	BindableProperty.Create(
		nameof(SelectedTabIndex), 
		typeof(int),
		typeof(MyTabbedPage), 0,
		BindingMode.TwoWay, null,
		propertyChanged: OnSelectedTabIndexChanged);
static void OnSelectedTabIndexChanged
	(BindableObject bindable, object oldValue, object newValue)
{
	if (((MyTabbedPage)bindable)._isTabPageVisible)
	{
		// update the Selected Child-Tab page 
		// only if Tabbed Page is visible..
		((MyTabbedPage)bindable).CurrentPage 
		= ((MyTabbedPage)bindable).Children[(int)newValue];
	}
}
public int SelectedTabIndex
{
	get { return (int)GetValue(SelectedTabIndexProperty); }
	set { SetValue(SelectedTabIndexProperty, value); }
}

 

Looks neat eh, so its a simple Bindable property as you can see, but however we’re handling it’s OnSelectedTabIndexChanged event ourselves because when the value changes from ViewModel’s end we need to update it on our UI’s end, as you can see we’re having a little flag property inside our MyTabbedPage 

3. the ViewModel…

Now is the time for MyTabbedPageViewModel stuff to come along. Nothing fancy just a standard ViewModel, but we need a reference to the IoC container (whichever it is you’re using) because we need to register our interface instance in it. This ViewModel as we discussed before is going to implement our IMyTabbedPageSelectedTab interface and its method and property.

public class MyTabbedPageViewModel 
          : ViewModelBase, IMyTabbedPageSelectedTab
{
     private readonly IUnityContainer _unityContainer;

     private int _selectedTab;
     /// <summary>
     /// Binds to the View's property
     /// View-ViewModel communcation
     /// </summary>
     public int SelectedTab
     {
          get { return _selectedTab; }
          set
          {
             SetProperty(ref _selectedTab, value);
             Title = $"My Tabbed Page - Tab [{SelectedTab + 1}]";
          }
     }
     
     public MyTabbedPageViewModel
          (INavigationService navigationService,
                         IUnityContainer unityContainer)
          : base(navigationService)
     {
          Title = $"My Tabbed Page - Tab [{SelectedTab + 1}]";

          this._unityContainer = unityContainer;

          // register this instance so we can access 
          // IMyTabbedPageSelectedTab anywhere in the code
          _unityContainer.RegisterInstance<IMyTabbedPageSelectedTab>
                    (this, new ContainerControlledLifetimeManager());
     }

     public void SetSelectedTab(int tabIndex)
     {
          SelectedTab = tabIndex;
     }
}

 

The SelectedTab property in the ViewModel is the one that’s binding to the SelectedTabIndex property in the MyTabbedPage, now you can see the bridge between the View-ViewModel.

Here we’re registering this ViewModel instance by the type of IMyTabbedPageSelectedTab so that we can access it from anywhere using the same type and also we’re passing in ContainerControlledLifetimeManager() parameter because we need to make sure that instance is properly managed by the container and garbage collected later when not in use.

4. finally Consume it…

So here is the little Magic code snippet you need to execute, wherever you wish to have access to programatically switching the Selected Child-Tab of our MyTabbedPage.

_unityContainer.Resolve<IMyTabbedPageSelectedTab>().SetSelectedTab(tabIndex);

 

You simply access the registered service interface and call on the SetSelectedTab() or simply you could also call the IMyTabbedPageSelectedTab.SelectedTab property directly as well. 😉

Just a little note, well this may not be the best of all approaches but this is what I believe is a better solution given my experience and expertise. But if you have a better alternative, please feel free to share!

Let’s fire it up!

So here’s this bad boy in action…

 

That’s the Child-Tab being switched programatically while inside the TabbedPage!

 

And here’s how nicely the Child-Tabs are switching programatically while outside the TabbedPage! As you can see when coming back to the TabbedPage, it nicely moves to the Selected Child-Tab…

Eyyy look at that! 😀

How about UnitTest-ing…

Uh fine, let me show you. 😛

In my case I used xUnit.net for my Test project, along side Prism.Forms and Xamarin.Forms.Mocks for mocking Xamarin.Forms run time.

Switching between Child-Tabs inside the TabbedPage:

//  Let's Tab-Navigate to TabChild2Page
_appInstance.Container.Resolve<TabChild1PageViewModel>()
			.GoToNextTabCommand.Execute("1");

//  Am I in the MyTabbedPage-> TabChild2Page?
Assert.IsType<TabChild2PageViewModel>
			(myTabbedPage.CurrentPage.BindingContext);

//  Let's Tab-Navigate to TabChild3Page
_appInstance.Container.Resolve<TabChild2PageViewModel>()
			.GoToNextTabCommand.Execute("2");

//  Am I in the MyTabbedPage-> TabChild2Page?
Assert.IsType<TabChild3PageViewModel>
			(myTabbedPage.CurrentPage.BindingContext);

 

I’m calling the Commands through my child page’s ViewModel and switching the Selected Child-Tab and then asserting to make sure the myTabbedPage instance has updated accordingly.

Switching between Child-Tabs outside the TabbedPage:

//  Am I inside the DetailPage?
Assert.IsType<DetailPageViewModel>
		    (navigationStack.Last().BindingContext);

// Let's go back to Tabbed Page -> TabChild3Page
_appInstance.Container.Resolve<DetailPageViewModel>()
		    .GoBackToTabChild3PageCommand.Execute();

//  Am I inside the MyTabbedPage?
Assert.IsType<MyTabbedPageViewModel>
		    (navigationStack.Last().BindingContext);

//  Am I in the MyTabbedPage-> TabChild3Page?
Assert.IsType<TabChild3PageViewModel>
		    (myTabbedPage.CurrentPage.BindingContext);

 

Here you can clearly see I’m calling the GoBackToTabChild3PageCommand in an page(DetailPage) which Ihave navigated to after the TabbedPage, and what happens in that command is I’m changing the Selected Child-Tab in the MyTabbedPage and immediately going back to it by exiting the DetailPage. Then I’m coming back to the MyTabbedPage, and the Child-Tab 3 is selected in the TabbedPage.

Here’s where you could take a look at the full test implementation : https://github.com/AdvPrismTabNavigation.xUnitTest

Voila! 😀 UnitTest-ing Done!

Github it if yo lazy!

So all of this is hosted on my git repo: https://github.com/AdvPrismTabNavigation

Feel free to grab your copy if you’re too lazy to DIY! 😛

That’s it for today.

Cheers all! 😀 Share the love!

Build your own Transparent Page from scratch for Xamarin.Forms…

There was this one time I wanted to build my own Transparent Page in Xamarin Forms, from scratch, all by myself, due to my ego and to challenge myself.

Usually when it comes to Transparent page related situations I would always recommend the awesome Rg.Plugins.Popup  library, which I had praised one of my previous blog posts as well, So I created a Popup with Transparent background in Xamarin Forms… 😉

Backstory…

But for real there was one instance I couldn’t use any 3rd party library for the project and all the code bits should be from scratch. So I had no option but to resort myself to creating my own Transparent Page in that Xamarin.Forms project.

And I did…

Sneak Peak…

So this how it would look like.

And limit of the expansion is all up to your imagination and developer skills.

If not work on it! 😛

Recipe time!

So to create a transparent page in Xamarin.Forms out of the box is impossible, which I’m not going to explain in detail. Obviously in short, for reasons such as Xamarin.Forms abstracts the most common subset of properties of the native platforms, we don’t have much power of customization of the UI.

There is no way to use Xamarin.Forms ContentPage with transparency. (Yes I have tried!) So we need something beyond Xamarin.Forms stuff, Aha! Natively Rendered View, that could overlay on top of a give ContentPage.

But that doesn’t mean Xamarin.Forms would block you from implementing something platform specific, it only empowers you 😉

Also since we’re drilling down in the native levels, we have absolute control over Xamarin.Forms Pages, including the power to push any View on top of Xamarin.Forms ContentPage Navigation stack.

Recipe in-depth!

So to do this we need to have some Native platform level access, so if you’re using a Xamarin.Forms shared project, this should be pretty easy, but for PCL projects, you may have to create a dependency service implementation to invoke this implementation.

So in Android, we’re going to use Dialog View to implement the transparent Page and with the access of the Activity instance, we’ll push it to over any give ContentPage of Xamarin.Forms.

Then in iOS, we’ll be using UIApplication instance’s KeyWindow property to push the transparent Page over any given ContentPage of Xamarin.Forms.

Sounds pretty straight forward eh! 😀

Xamarin.Forms bits…

Alright since this a Xamarin.Forms Transparent Page, let’s first create our usual ContentPage, with usual stuff.

var xamFormsPage = new ContentPage() 
{
  BackgroundColor = new Color(0, 0, 0, 0.5),
  Content =
  new StackLayout() 
  {
    Padding = 30,
    Spacing = 20,
    WidthRequest = 250,
    BackgroundColor = Color.Black,
    Children = 
	{
	 new Xamarin.Forms.Label() {
	  Text =
	   "Welcome to my own Transparent Page!",
	   FontAttributes = FontAttributes.Bold,
	   TextColor = Color.White,
	   FontSize = 20,
	 },
	 new Xamarin.Forms.Label() {
	  Text =
	   "This is from Xamarin.Forms with a " +
	   "bit mix of simple native magic!",
	   TextColor = Color.White,
	   FontSize = 17,
	 },
	 new Xamarin.Forms.Button() {
	  Text = "Close me!",
	   BackgroundColor = Color.Gray,
	   TextColor = Color.White,
	 }
    },
    VerticalOptions = LayoutOptions.Center,
    HorizontalOptions = LayoutOptions.Center,
  }
};

 

So here we have an instance of a simple Xamarin.Forms.Content page, with a bunch of labels and a button. This is the page we’re going to render into a transparent page. 😉

Android Implementation…

So like we discussed before, on Android we’re going to make use of the Android Dialog View to populate our transparent page. In order to do this we need to get access to the current Activity of our Xamarin.Forms Android run time.

In order to do that we’re going to use CrossCurrentActivity plugin by James Montemagno. So before we begin, go ahead and add that plug in to your Xamarin.Forms solution using Nuget.

Now the basic idea here is all about actually rendering our Xamarin.Forms ContentPage instance, and converting it to a native Android View at run time. Then we take that native View instance and attach into a Android Dialog View, making it visible along with the transparent effect. Oh yes the CrossCurrentActivity plugin comes handy when we instantiate our Android Dialog View. 😉

// Assign the Parent hook for our page instance 
xamFormsPage.Parent = Xamarin.Forms.Application.Current.MainPage;

// Run the Layout Rendering Cycle for the page
xamFormsPage.Layout(new Rectangle(0, 0,
 Xamarin.Forms.Application.Current.MainPage.Width,
 Xamarin.Forms.Application.Current.MainPage.Height));

// Get the native renderered instance for our page
var nativePageRendererInstance = xamFormsPage.GetOrCreateRenderer();

// Get the native page for our page
Android.Views.View nativePageView = nativePageRendererInstance.View;

// Create the native transparent Dialog instance to embed our page
Dialog dialog = new Dialog(CrossCurrentActivity.Current.Activity);
dialog.RequestWindowFeature((int) WindowFeatures.NoTitle);
dialog.SetCancelable(false);
dialog.SetContentView(nativePageView);
Window window = dialog.Window;
window.SetLayout(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent);
window.ClearFlags(WindowManagerFlags.DimBehind);
window.SetBackgroundDrawable(new ColorDrawable(Android.Graphics.Color.Transparent));

// Show the page
dialog.Show();

 

There you have the magical code 😉 lol.

You can see how we’re setting the Parent hook to our Xamarin.Forms page instance, then running the Layout() rendering circle allowing the Views to be actually measured and rendered in the memory. Then we convert our Xamarin.Forms page instance into a native Android View using the GetOrCreateRenderer() extension method which I will describe next.

Then as I discussed before we’re attaching the native View into a Dialog View and setting it visible resulting in total awesome transparency of a page, along with the exact Xamarin.Forms content we wanted to display.

Oh before I forget here is the precious Xamarin.Forms.View -> Android.Views.View Converter extension implementation. Special thanks to rotorgames for the below magical code block. 😉

internal static class PlatformExtension
{
	public static IVisualElementRenderer GetOrCreateRenderer(this VisualElement bindable)
	{
		var renderer = XFPlatform.GetRenderer(bindable);
		if (renderer == null)
		{
			renderer = XFPlatform.CreateRendererWithContext(bindable, CrossCurrentActivity.Current.Activity);
			XFPlatform.SetRenderer(bindable, renderer);
		}
		return renderer;
	}
}

Source Credit: Rg.Plugins.Popup.Droid/PlatformExtension.cs

As you can see it’s a simple implementation that takes in the Xamarin.Forms View instance and retrieve the native renderer for that View.

Now when you need to hide the above Transparent page, you simply call Hide() on the Android Dialog instance.

// Hide the page
dialog.Hide();

 

Then we go to the iOS stuff..

iOS Implementation….

Here we’ve come to the iOS implementation, so just like we discussed in the beginning, we’re going to access the global UIApplication singleton to push our transparent page the application view through the KeyWindow property.

So in a nutshell iOS renders every native View with the transparency give the proper background spacing, so we don’t really have to worry about using any placeholder view. The idea here is to get our Xamarin.Forms Page instance, run its Layout rendering cycle, convert that instance to an iOS native View. Then finally push it to the KeyWindow property by adding as a SubView.

Pretty straightforward, almost similar as to what we did in Android but simpler! 😉

// Assign the Parent hook for our page instance 
xamFormsPage.Parent = Xamarin.Forms.Application.Current.MainPage;

// Run the Layout Rendering Cycle for the page
xamFormsPage.Layout(new Rectangle(0, 0,
 Xamarin.Forms.Application.Current.MainPage.Width,
 Xamarin.Forms.Application.Current.MainPage.Height));

// Get the native renderered instance for our page
var nativePageRendererInstance = xamFormsPage.GetOrCreateRenderer();

// Get the native page for our page
UIView nativePageView = nativePageRendererInstance.NativeView;

// Show the page by pushing to the stack
UIApplication.SharedApplication.KeyWindow.AddSubview(nativePageView);

 

I’m not going repeat myself here because I’m too lazy and the explanation is almost same as I did in Android implementation. 😀

But in the context of iOS, you can see we’re getting the iOS native UIView of our Xamarin.Forms ContentPage instance and pushing it directly to the Application UI, by calling AddSubView() on KeyWindow property.

Oh before I forget here is the precious Xamarin.Forms.View -> UIKit.UIView Converter extension implementation. Special thanks to rotorgames for the below magical code block. 😉

internal static class PlatformExtension
{
	public static IVisualElementRenderer GetOrCreateRenderer(this VisualElement bindable)
	{
		var renderer = XFPlatform.GetRenderer(bindable);
		if (renderer == null)
		{
			renderer = XFPlatform.CreateRenderer(bindable);
			XFPlatform.SetRenderer(bindable, renderer);
		}
		return renderer;
	}
}

Source Credit: Rg.Plugins.Popup.IOS/PlatformExtension.cs

Now when you want to hide the above created Transparent Page, then you simple call the RemoveFromSuperview() on our iOS UIView instance, which will result in it removing itself from UIWindow.

// Hide the page
nativePageView.RemoveFromSuperview();

 

bloopity blah! 😀

Alright, so let me address something you might be wondering…

How about Xamarin.Forms to Xamarin Native bridge?

Now you might ask how am I going to bridge the above explained Xamarin.Forms and Xamarin Native implementation counterparts together? Now that’s some easy peasy nibbles I’m gonna leave up to your creativity or requirement.

There’s many ways to call back and forth between Xamarin.Forms or Xamarin Native project levels, or in other words, between the PCL project and the Platform Specific projects. For starters, you could use Xamarin Dependency Service to register a service interface and concrete implementation to communicate between these two layers back and forth. 😉 And many other possibilities, so your creativity is the limit.

However I will probably be writing another blog post regarding this with a full implementation of this with some cool application of it! 😉

Well frankly, that’s it fellas.

Cheers! 😀

Ze Flippable View in Xamarin.Forms with Native Animations…

Let’s blend some Native Animation goodness to our Flippin’ Flipity Flippable View in Xamarin.Forms…

So I hop yol’ remember my previous post, It’s a Flippin’ Flipity Flippable View in Xamarin.Forms! where I showcased my awesome control built right from Xamarin.Forms without any native code implementation. 😉

  

But you may have noticed a slight issue in the Flip Animation, specially on Android and iOS as well (slightly though), where Flip animation moves the View out of it’s bounds.

^As you can see above, in the animation screenshots… 😮

Some improvement needed…

If you look closely, during the flip rotation, the View sort of scales up itself and moves out of the bounds of itself and scales back and revert back to the normal bounds.

This was kind of annoying me from a personal perspective, so that’s why I thought of finding a solution by trying to render the whole animation natively for Android and iOS separately. 😀

Behold ze Native Animation…

So basically the whole logic of the FlipViewControl is going to be the same, only the animation part would be executed natively. Let’s discuss how we could implement a native animation for each Android and iOS below. 😀

As of Android…

As of Android, the reason why the View scales out of bounds during the flip animation is because that is the default behavior of Flip Animation in Android. Since Xamarin.Forms Aniamtions binds to the native default behavior you could definitely expect it to behave that way. There’s an aspect called Camera View distance perspective for any given view, by default during any animation the Camera View aspect doesn’t change, thus causing the overblown effect of the Flip Animation.

So by implementing a native animation what we could achieve is to control the Camera View Distance value for each animation frame manually, also something to keep in mind this needs to be done according to the Screen density. I found this solution thanks to this forum post:  https://forums.xamarin.com/discussion/49978/changing-default-perspective-after-rotation

As of iOS…

Here for the iOS its not much of an issue, but you do see a bit of the View scaling out of the boundary. So let’s dive into the iOS native flip animation.

We’ll be using a CATransform3D to maintain the transformation of the View’s Layer and execute the animation using UIView.Animate(), we will be using two CATransform3D objects to make sure the View doesn’t scale beyond the boundaries during the animation. This whole awesome solution I found via a random snippet search https://gist.github.com/aloisdeniel/3c8b82ca4babb1d79b29

Time for some coding…

Let’s get started off with the subclassed custom control, naming it XNFlipView and the implementation is actually same as our previous XFFlipView control implementation, but the only difference is there’s no Xamarin.Forms Animation implementation, or handling of the IsFlipped property in the PCL code, since it will be handled in the Renderer level.

public class XNFlipView : ContentView
{
	public XNFlipView()
	{
		...
	}

	public static readonly BindableProperty FrontViewProperty
	...

	public static readonly BindableProperty BackViewProperty
	...
	
	// Everything else is same as XFFlipView implementation

	public static readonly BindableProperty IsFlippedProperty =
	BindableProperty.Create(
		nameof(IsFlipped),
		typeof(bool),
		typeof(XNFlipView),
		false,
		BindingMode.Default,
		null);

	/// <summary>
	/// Gets or Sets whether the view is already flipped
	/// ex : 
	/// </summary>
	public bool IsFlipped
	{
		get { return(bool)this.GetValue(IsFlippedProperty);}
		set { this.SetValue(IsFlippedProperty, value); }
	}
	
	...
}

 

You can take a look at the full class implementation in the github repo file: XFFlipViewControl/XNFlipView.cs

Native Renderers implementation…

Since the animations are going to be handled natively, we need to create the Custom Renderers for our XNFlipView for Android and iOS separately, so let’s get started…

Android Custom Renderer

Alright then let’s go ahead and create the XNFlipViewRenderer  extending from ViewRenderer, as of Xamarin.Forms 2.5 and later we have to pass the Context in the Custom Renderer’s constructor, so let’s begin with that.

public class XNFlipViewRenderer : ViewRenderer
{
	private float _cameraDistance;

	private readonly ObjectAnimator _animateYAxis0To90;
	private readonly ObjectAnimator _animateYAxis90To180;

	public XNFlipViewRenderer(Context context) : base(context)
	{
		...
		//Animation Initialization
		...
	}

	protected override void 
		OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e)
	{
		base.OnElementChanged(e);

		if (((XNFlipView)e.NewElement) != null)
		{
			// Calculating Camera Distance 
                        //to be used at Animation Runtime
			// https://forums.xamarin.com/discussion/49978/changing-default-perspective-after-rotation
			var distance = 8000;
			_cameraDistance = Context.Resources.DisplayMetrics.Density * distance;
		}
	}

	protected override void 
		OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
	{
		base.OnElementPropertyChanged(sender, e);

		if (e.PropertyName == XNFlipView.IsFlippedProperty.PropertyName)
		{
			if (!((XNFlipView)sender).IsFlipped)
			{
				this.RotationY = 0;
			}

			AnimateFlipHorizontally();
		}
	}

	private void AnimateFlipHorizontally()
	{
		SetCameraDistance(_cameraDistance);

		_animateYAxis0To90.Start();
	}
}

 

Now as you can see above in the constructor we’re initializing the ObjectAnimator objects _animateYAxis0To90 and _animateYAxis90To180 which will be executing the native Flip Animation.

Then in the Renderer’s OnElementChanged we’re calculating the Camera distance value to be used during the Animations execution as we explained before in the concept.

Also you can see how we’re listening to the XNFlipView.IsFlipped value change and executing Animations.

Next let’s take a look into the Animation execution implementation which goes inside the Constructor as you can see in the previous code snippet…

// Initiating the first half of the animation
_animateYAxis0To90 = ObjectAnimator.OfFloat(this, "RotationY", 0.0f, -90f);
_animateYAxis0To90.SetDuration(500);
_animateYAxis0To90.Update += (sender, args) =>
{
	// On every animation Frame we have to update the Camera Distance since Xamarin overrides it somewhere
	SetCameraDistance(_cameraDistance);
};
_animateYAxis0To90.AnimationEnd += (sender, args) =>
{
	if (((XNFlipView)Element).IsFlipped)
	{
		// Change the visible content
		((XNFlipView)Element).FrontView.IsVisible = false;
		((XNFlipView)Element).BackView.IsVisible = true;
	}
	else
	{
		// Change the visible content
		((XNFlipView)Element).BackView.IsVisible = false;
		((XNFlipView)Element).FrontView.IsVisible = true;
	}

	this.RotationY = -270;

	_animateYAxis90To180.Start();
};

// Initiating the second half of the animation
_animateYAxis90To180 = ObjectAnimator.OfFloat(this, "RotationY", -270f, -360f);
_animateYAxis90To180.SetDuration(500);
_animateYAxis90To180.Update += (sender1, args1) =>
{
	// On every animation Frame we have to update the Camera Distance since Xamarin overrides it somewhere
	SetCameraDistance(_cameraDistance);
};

 

As you can see we’re instantiating the animation objects accordingly to the degree angle of the Y Axis they’re suppose to animate the view. Also something very important is that in each animation frame we’re also updating the Camera View Distance, as we discussed earlier this to prevent the View from scaling beyond it’s boundaries. That SetCameraDistance() call takes of it with the previous calculated value. 😉

You can also change the speed of the animation by changing the SetDuration() parameters, which currently I’ve set to 1 second.

You could take a look at the full implementation of the android custom renderer in the github file: XFFlipViewControl.Android/XNFlipViewRenderer.cs

iOS Custom Renderer

Alright then let’s move to the iOS Custom Renderer…

public class XNFlipViewRenderer : ViewRenderer

   protected override void
       OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
   {
       base.OnElementPropertyChanged(sender, e);

       if (e.PropertyName == XNFlipView.IsFlippedProperty.PropertyName)
       {
           if (((XNFlipView)sender).IsFlipped)
           {
             AnimateFlipHorizontally(NativeView, false, 0.5, () =>
             {
                 // Change the visible content
                 ((XNFlipView)sender).FrontView.IsVisible = false;
                 ((XNFlipView)sender).BackView.IsVisible = true;

                 AnimateFlipHorizontally
                           (NativeView, true, 0.5, null);
             });
           }
           else
           {
             AnimateFlipHorizontally(NativeView, false, 0.5, () =>
             {
                 // Change the visible content
                 ((XNFlipView)sender).FrontView.IsVisible = true;
                 ((XNFlipView)sender).BackView.IsVisible = false;

                 AnimateFlipHorizontally
                             (NativeView, true, 0.5, null);
             });
           }
       }
   }
   
   public void AnimateFlipHorizontally(...)
   {
       ...
   }

 

So here in iOS Renderer, it seems a bit straight forward as we’re simply listening to the IsFlipped property change and directly executing the animation.

Next let’s see the Animation implementation…

//https://gist.github.com/aloisdeniel/3c8b82ca4babb1d79b29
public void AnimateFlipHorizontally
	(UIView view, bool isIn, 
		double duration = 0.3, Action onFinished = null)
{
	var m34 = (nfloat)(-1 * 0.001);

	var minTransform = CATransform3D.Identity;
	minTransform.m34 = m34;
	minTransform = minTransform.
		Rotate((nfloat)((isIn ? 1 : -1) * Math.PI * 0.5),
			(nfloat)0.0f, (nfloat)1.0f, (nfloat)0.0f);
	var maxTransform = CATransform3D.Identity;
	maxTransform.m34 = m34;

	view.Layer.Transform = isIn ? minTransform : maxTransform;
	UIView.Animate(duration, 0, UIViewAnimationOptions.CurveEaseInOut,
		() => {
			view.Layer.AnchorPoint = new CGPoint((nfloat)0.5, (nfloat)0.5f);
			view.Layer.Transform = isIn ? maxTransform : minTransform;
		},
		onFinished
	);
}

 

So that’s basically the animation implementation code, which I have extracted from the given gist link at the top, which I have explained in the concept description as well.

You can change the speed of the flip animation by changing the duration.

You could take a look at the full implementation of the android custom renderer in the github file: XFFlipViewControl.iOS/XNFlipViewRenderer.cs

Try it out eh! 😀

Well its use is exactly same as our previous XFFlipView Control. As of an example you could take a look here in my github file: XNFlipViewDemoPage.xaml

So now to execute the awesome Flip Animation, simply change the value of the IsFlipped as follows.

XNFlipViewControl1.IsFlipped = !XNFlipViewControl1.IsFlipped;

 

As you can see in code behind, we’re changing the value of the control’s IsFlipped property, Simples eh! 😀 This is fully bindable as well, so you can directly bind this to a ViewModel property as well.

...
<xfFlipViewControl:XNFlipView 
     x:Name="XNFlipViewControl1" 
          IsFlipped="{Binding IsViewFlipped}">
...

</xfFlipViewControl:XNFlipView>

 

So you can directly use this in your beautifully crafted MVVM Xamarin.Forms app as well. 😀

Some Live Action…

Here we go baby! iOS and Android running side by side…

 

 

Woot!

Look at that the Flip Animation maintains the Bounds of the View nicely during the animation in both Android and iOS! 😉

This whole awesome project i hosted up in my Github repo : https://github.com/UdaraAlwis/XFFlipViewControl 

Cheers! 😀 Keep on going my fellow devs!

Spread the love…

It’s a Flippin’ Flipity Flippable View in Xamarin.Forms!

Something that Flips! Flipity Flippy Flippin’ Flip View right out of Xamarin.Forms yol! 😀

Sometime back while I was trying to push the limits of Xamarin.Forms Views, I came across this requirement of Flipping a View with a cool animation. So let me share the story of it right here as usual…

I wanted to create a control that would have a Front View and a Back View, whilst being able to switch between those two Views in with a cool Flip animation!

Behold ze me effortz… 😀

 

TADAAA! 😀 How cool it is eh! 😉

And its all pure Xamarin.Forms, without a single line of native code… Say whuut! 😀 lol

So yeah let’s see how I did it.

The Golden Recipe…

So the solution here is to simply use a View which can hold two layouts (where we will be placing out child elements in) on top of each other, and rotate the View with the easy use of  Xamarin.Forms Animations, whitest swapping the two layouts on top of each other accordingly.

Ok so let me elaborate step by step.

  • Prepare a MainLayout View to hold two child Layouts (FrontView and BackView) in it
  • Add the FrontView and BackView on top of each other inside the MainLayout  View
  • Rotate the MainLayout 90 degrees using Xamarin.Forms Animations API
  • Swap the FrontView and BackView 
  • Then Rotate the MainLayout another 90 degrees
  • And Repeat the same…

That’s it!

The Golden Control…

Alright let’s start of with creating a custom control, which we shall call the golden XFFlipView which would derive from a ContentView. Then myself be using a RelativeLayout as the Parent Layout View of this control,

I’m using bindable FrontViewProperty and BackViewProperty inside the XFFlipView control to hold the reference of the two child Layout Views that we are going to be using as FrontView and BackView of this Flippin’ Flippity Flippy thing! 😀

Additionally we are going to use a bindable boolean, IsFlippedProperty to handle the flipping of this flip view 😉

Well why all the “bindable properties” you might ask? Oh come on, why not silly! So we can monitor the changes of those properties at run time and react accordingly, such as the IsFlipped property, whereas whenever the value changes we shall be activating the Flip View animation functionality.

public class XFFlipView : ContentView
{
	private readonly RelativeLayout _contentHolder;
	
	public XFFlipView()
	{
		_contentHolder = new RelativeLayout();
		Content = _contentHolder;
	}

	public static readonly BindableProperty FrontViewProperty =
	BindableProperty.Create(...);

	public static readonly BindableProperty BackViewProperty =
	BindableProperty.Create(...);

	public static readonly BindableProperty IsFlippedProperty =
	BindableProperty.Create(...);

	private static void IsFlippedPropertyChanged(BindableObject bindable, object oldValue, object newValue)
	{
		if ((bool)newValue)
		{
			((XFFlipView)bindable).FlipFromFrontToBack();
		}
		else
		{
			((XFFlipView)bindable).FlipFromBackToFront();
		}
	}
	
	/// <summary>
	/// Performs the flip
	/// </summary>
	private async void FlipFromFrontToBack()
	{
		...
	}

	/// <summary>
	/// Performs the flip
	/// </summary>
	private async void FlipFromBackToFront()
	{
		...
	}
}

 

There you have it as we just discussed earlier. Ops I may have forgotten about those two methods at the bottom, so those are the methods we are going to use the actual Flip Animation logic, as you can see they’re are being called every time the IsFlipped property is changed.

Oh for them lazy fellas, here grab the full implementation above on my github: XFFlipView.cs

Ze Animationalization…

Alright time for the reveal of the animation thingy, which has been completely done through the easy to use Xamarin.Forms Animations API. Surprise!!?? 😛

...
private async void FlipFromFrontToBack()
{
	await FrontToBackRotate();

	// Change the visible content
	this.FrontView.IsVisible = false;
	this.BackView.IsVisible = true;

	await BackToFrontRotate();
}
...

So basically that’s the implementation of the above said mystery two methods, as you can clearly see, inside there I’m calling another method called FrontToBackRotate() which is the actual method that performs the animation. And right after that we are swapping the Visibility of the FrontView and BackView. Then continue with the rest of animation in BackToFrontRotate() call, just like how we discussed at the beginning.

Let’s see the actual animation implementation, shall we…

#region Animation Stuff

private async Task<bool> FrontToBackRotate()
{
	ViewExtensions.CancelAnimations(this);

	this.RotationY = 360;

	await this.RotateYTo(270, 500, Easing.Linear);

	return true;
}

private async Task<bool> BackToFrontRotate()
{
	ViewExtensions.CancelAnimations(this);

	this.RotationY = 90;

	await this.RotateYTo(0, 500, Easing.Linear);

	return true;
}

#endregion

 

Oh look at that simplicity eh! Thank you Xamarin.Forms animation! 😀 lol

So what happen over there is first we cancel any pending animation and the do initial Y axis rotate property of the parent View and then actually call on the RotateYTo() of Xamarin.Forms Animations, causing it the parent Layout to rotate around the Y Axis with the given value of degrees.

Then when the parent View is flipping from Back To Front View, the same process’s opposite will be executed. 😀 Simples!

Try it out eh! 😀

Since its full on Xamarin.Forms without a single line of native Xamarin code, you could straightaway use this in your XAML or C# code behind anywhere in your PCL.

<xfFlipViewControl:XFFlipView 
        x:Name="XFFlipViewControl1">

    <xfFlipViewControl:XFFlipView.FrontView>
        <Frame
            Margin="10"
            Padding="0"
            BackgroundColor="#0080ff"
            CornerRadius="10"
            HasShadow="True">
            <Grid>
                <Label
                 Grid.Row="0"
                 FontAttributes="Bold"
                 FontSize="Large"
                 HorizontalTextAlignment="Center"
                 Text="this is front view"
                 TextColor="White"
                 VerticalTextAlignment="Center" />
            </Grid>
        </Frame>
    </xfFlipViewControl:XFFlipView.FrontView>

    <xfFlipViewControl:XFFlipView.BackView>
        <Frame
            Margin="10"
            Padding="0"
            BackgroundColor="#ff0080"
            CornerRadius="10"
            HasShadow="True">
            <Grid>
                <Label
                 Grid.Row="0"
                 FontAttributes="Bold"
                 FontSize="Large"
                 HorizontalTextAlignment="Center"
                 Text="this is back view"
                 TextColor="White"
                 VerticalTextAlignment="Center" />
            </Grid>
        </Frame>
    </xfFlipViewControl:XFFlipView.BackView>

</xfFlipViewControl:XFFlipView>

 

Woot! Such simplicity! 😀 So you can see how I have directly used our awesome XFFlipView control right inside XAML and defined the Front and Back Views. Also I have used a Frame View to make it look cooler 😉 lol

So now to execute the awesome Flip Animation, simply change the value of the IsFlipped as follows.

XFFlipViewControl1.IsFlipped = !XFFlipViewControl1.IsFlipped;

 

As you can see in code behind, we’re changing the value of the control’s IsFlipped property, Simples eh! 😀 This is fully bindable as well, so you can directly bind this to a ViewModel property as well.

...
<xfFlipViewControl:XFFlipView 
     x:Name="XFFlipViewControl1" 
          IsFlipped="{Binding IsViewFlipped}">
...

</xfFlipViewControl:XFFlipView>

 

So you can directly use this in your beautifully crafted MVVM Xamarin.Forms app as well. 😀

Some Live Action…

Here we go baby! iOS and Android running side by side…

  

Oh hold on… there’s more coolness… 😀

 

Ohhh! Eye Candy! 😀

And the craziest thing about it is that, all of this awesomeness is right from Xamarin.Forms, without a single line of native Xamarin code. 😉

Woot!

This whole awesome project i hosted up in my Github repo : https://github.com/UdaraAlwis/XFFlipViewControl 

Oh BTW, you might ask me why on Android during the Animation, the view seem to be expanding out of the view? Yes its basically how the Android native flip animation executes, since Xamarin.Forms directly maps its Animation rendering calls down to native level. But we could easily tweak it up by implementing our own native renderer for the Animation, which we will be looking into in the next post. 🙂

Cheers! 😀 Keep on going my fellow devs!

Spread the love…

Let’s Override Navigation Bar back button click in Xamarin Forms…

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…

😛

Blah blah…

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…

owwhh SNAP!

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….

Android

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. 😉

iOS

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

namespace WhateverYourNamespace
{
    public class CoolContentPage : ContentPage
    {
        /// <summary>
        /// Gets or Sets the Back button click overriden custom action
        /// </summary>
        public Action CustomBackButtonAction { get; set; }

        public static readonly BindableProperty EnableBackButtonOverrideProperty =
               BindableProperty.Create(
               nameof(EnableBackButtonOverride),
               typeof(bool),
               typeof(CoolContentPage),
               false);
			   
        /// <summary>
        /// Gets or Sets Custom Back button overriding state
        /// </summary>
        public bool EnableBackButtonOverride
        {
            get
            {
                return (bool)GetValue(EnableBackButtonOverrideProperty);
            }
            set
            {
                SetValue(EnableBackButtonOverrideProperty, value);
            }
        }
    }
}

 

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.

public override bool OnOptionsItemSelected(IMenuItem item)
{
	// check if the current item id 
	// is equals to the back button id
	if (item.ItemId == 16908332)
	{
	   // retrieve the current xamarin forms page instance
	   var currentpage = (CoolContentPage)
	   Xamarin.Forms.Application.
	   Current.MainPage.Navigation.
	   NavigationStack.LastOrDefault();

	   // check if the page has subscribed to 
	   // the custom back button event
	   if (currentpage?.CustomBackButtonAction != null)
	   {
		 // invoke the Custom back button action
		 currentpage?.CustomBackButtonAction.Invoke();
		 // and disable the default back button action
		 return false;
	   }

	   // if its not subscribed then go ahead 
	   // with the default back button action
	   return base.OnOptionsItemSelected(item);
	}
	else
	{
	   // since its not the back button 
	   //click, pass the event to the base
	   return base.OnOptionsItemSelected(item);
	}
}

public override void OnBackPressed()
{
	// this is not necessary, but in Android user 
	// has both Nav bar back button and
	// physical back button its safe 
	// to cover the both events

	// retrieve the current xamarin forms page instance
	var currentpage = (CoolContentPage)
	Xamarin.Forms.Application.
	Current.MainPage.Navigation.
	NavigationStack.LastOrDefault();

	// check if the page has subscribed to 
	// the custom back button event
	if (currentpage?.CustomBackButtonAction != null)
	{
		currentpage?.CustomBackButtonAction.Invoke();
	}
	else
	{
		base.OnBackPressed();
	}
}

 

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…

public override void ViewWillAppear(bool animated)
{
     base.ViewWillAppear(animated);
     
     if (((CoolContentPage)Element).EnableBackButtonOverride)
     {
          SetCustomBackButton();
     }
}

private void SetCustomBackButton()
{
     // Load the Back arrow Image
     var backBtnImage = 
     UIImage.FromBundle("iosbackarrow.png");

     backBtnImage = 
     backBtnImage.ImageWithRenderingMode
     (UIImageRenderingMode.AlwaysTemplate);

     // Create our Button and set Edge 
     // Insets for Title and Image
     var backBtn = new UIButton(UIButtonType.Custom)
     {
          HorizontalAlignment =   
          UIControlContentHorizontalAlignment.Left,
          TitleEdgeInsets = 
          new UIEdgeInsets(11.5f, 15f, 10f, 0f),
          ImageEdgeInsets = 
          new UIEdgeInsets(1f, 8f, 0f, 0f)
     };

     // Set the styling for Title
     // You could set any Text as you wish here
     backBtn.SetTitle("Back", UIControlState.Normal);
     // use the white color in ios back button text
     backBtn.SetTitleColor(UIColor.White,
     UIControlState.Normal); 
     backBtn.SetTitleColor(UIColor.LightGray, 
     UIControlState.Highlighted);
     backBtn.Font = UIFont.FromName("HelveticaNeue",
     (nfloat)17);

     // Set the Image to the button
     backBtn.SetImage(backBtnImage, UIControlState.Normal);

     // Allow the button to Size itself
     backBtn.SizeToFit();

     // Add the Custom Click event you would like to 
     // execute upon the Back button click
     backBtn.TouchDown += (sender, e) =>
     {
          // Whatever your custom back button click handling
          if(((CoolContentPage)Element)?.
          CustomBackButtonAction != null)
          {    
            ((CoolContentPage)Element)?.
               CustomBackButtonAction.Invoke();
          }
     };

     //Set the frame of the button
     backBtn.Frame = new CGRect(
          0,
          0,
          UIScreen.MainScreen.Bounds.Width / 4,
          NavigationController.NavigationBar.Frame.Height);

     // Add our button to a container
     var btnContainer = new UIView(
     new CGRect(0, 0, 
     backBtn.Frame.Width, backBtn.Frame.Height));
     btnContainer.AddSubview(backBtn);

     // A dummy button item to push our custom  back button to
     // the edge of screen (sort of a hack)
     var fixedSpace = 
     new UIBarButtonItem(UIBarButtonSystemItem.FixedSpace)
     {
          Width = -16f
     };
     // wrap our custom back button with a UIBarButtonItem
     var backButtonItem = new UIBarButtonItem("",
     UIBarButtonItemStyle.Plain, null)
     {
          CustomView = backBtn
     };

     // Add it to the ViewController
     NavigationController.TopViewController.
     NavigationItem.LeftBarButtonItems 
     = new[] { fixedSpace, backButtonItem };
}

 

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.

<WhateverYourNamespace:CoolContentPage 
 xmlns="http://xamarin.com/schemas/2014/forms"
 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
 xmlns:WhateverYourNamespace=
 "clrnamespace:XFNavBarBackBtnClickOverride;
 assembly=XFNavBarBackBtnClickOverride"
 x:Class="XFNavBarBackBtnClickOverride.Page2"             
 Title="Page 3"
 EnableBackButtonOverride="True"
 BackgroundColor="#00bfff">
  <StackLayout
    Spacing="20"
    Padding="20,10,20,10"
    VerticalOptions="Center"
    HorizontalOptions="Center" >

    <Label Text="This is the cool page, 
	which has the Navigation Bar Back button 
	click overriden. How go ahead and click that Back     
        button! ;)"
           FontSize="20"
           HorizontalTextAlignment="Center"
           TextColor="White"/>
    
  </StackLayout>
</WhateverYourNamespace:CoolContentPage>

 

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.

namespace WhateverYourNamespace
{
    public partial class Page2 : CoolContentPage
    {
        public Page2()
        {
            InitializeComponent();
            
            if (EnableBackButtonOverride)
            {
                this.CustomBackButtonAction = async () =>
                {
                    var result = await this.DisplayAlert(null,
                        "Hey wait now! are you sure " +
                        "you want to go back?",
                        "Yes go back", "Nope");

                    if (result)
                    {
                        await Navigation.PopAsync(true);
                    }
                };
            }
        }
    }
}

 

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!

Creating an identical Custom Navigation Bar Back Button in Xamarin iOS…

Now there comes a time when the Developer has to override or customize the Back Button in their Xamarin iOS app. Well I’ve been there, hence let me share my experience…

Now the origin of my experience is that, I wanted to override the Back button click event of my Xamarin iOS, but since there’s no way to actually “override” the back button event, I had to completely get rid of the default back button and implement my own custom back button, but it had to be exactly similar as the original iOS back button…

45ffk

So let me ask you…

Have you ever wanted to override your Navigation Bar Back button in iOS  with Xamarin? or specially override it with an identical or similar looking custom button? may be to gain control of the Back button click event?

Then this post is for you… 😀

tumblr_inline_nl7ryzqono1rkrh6k

Custom, but Similar to the actual Back Button…

Yes that’s right, let me highlight the identical or similar looking custom back button, because it’s pretty simple and straightforward to override or replace the back button, but its a bit of struggle when you want to implement a custom back button which looks identical or similar to the original back button in iOS.

The key…

So the key things to keep in mind is that,

  • We need use an Image with a “Back Arrow” that is similar from look and size of the original back button.
  • Use similar Font size to display the Text
  • Use necessary padding and x/y values to place the Image and Text Title properly

Alright, let’s get into it…

Image with Back Arrow…

Now to find the image for the Back Arrow just google “iphone back button png” or something similar, you could easily find lots, I would recommend to use the icons8 website, which is where I got mine, https://icons8.com/web-app/15157/back

Make sure there’s no padding between the Image pixel space and the borders, in my case the image was 24×41 size

screen-shot-2017-03-02-at-1-09-15-pm

Oh another thing, make sure the Image is PNG, White color with a transparent back ground, so that you can edit the Tint as you go later if needed… 🙂

Title Text Font…

So for this one, I had to do a bit of playing around, which I found that “HelveticaNeue” and Font Size 17 is perfect for this. 🙂

Time for the coding… 😉

So let’s start off with loading the UIImage and initializing our UIButton.

// Load the Back arrow Image
var backBtnImage = UIImage.FromBundle("iosbackarrow.png");

backBtnImage = 
	backBtnImage.ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate);

// Create our Button and set Edge Insets for Title and Image
var backBtn = new UIButton(UIButtonType.Custom)
{
	HorizontalAlignment = UIControlContentHorizontalAlignment.Left,
	TitleEdgeInsets = new UIEdgeInsets(11.5f, 15f, 10f, 0f),
	ImageEdgeInsets = new UIEdgeInsets(1f, 8f, 0f, 0f)
};

 

And set up the necessary Edge Insets for the button Title and Image as shown above. Well those values I figured out by playing around with the positioning values for hours.. 😛 lol

Next let’s dive into the Button’s customization…

// Set the styling for Title
// You could set any Text as you wish here
backBtn.SetTitle("Back", UIControlState.Normal);
// use the default blue color in ios back button text
backBtn.SetTitleColor(UIColor.FromRGB(0, 129, 249), UIControlState.Normal); 
backBtn.SetTitleColor(UIColor.LightGray, UIControlState.Highlighted);
backBtn.Font = UIFont.FromName("HelveticaNeue", (nfloat)17);

// Set the Image to the button
backBtn.SetImage(backBtnImage, UIControlState.Normal);

// Allow the button to Size itself
backBtn.SizeToFit();

 

Alright, that’s quite a bit of code to swallow, so first we set the Title Text of the button, and keep in mind you could set any Text as you wish there, for now I’m just using “Back” text.. 🙂

Next for the Text Color in the Normal state, I have used the default Blue color variation that iOS use by default, you could also use any color you prefer as well 🙂 Next we set the Highlight state of Text to Light Gray.

As we discussed at the beginning we will use HelveticaNeue with Font size of 17 for the Title Text. And finally set the Image to the Button and allow it to fit to the required size. 😀

// Add the Custom Click event you would like to 
// execute upon the Back button click
backBtn.TouchDown += (sender, e) =>
{
	// Whatever your custom back button click handling
};

 

Now here’s something very important, we need to make sure we handle our custom back button click as shown above… 😉

So next we shall do the preparation for the Frame.

//Set the frame of the button
backBtn.Frame = new CGRect(
	0,
	0,
	UIScreen.MainScreen.Bounds.Width / 4,
	NavigationController.NavigationBar.Frame.Height);

// Add our button to a container
var btnContainer = new UIView(
	new CGRect(0, 0, backBtn.Frame.Width, backBtn.Frame.Height));
btnContainer.AddSubview(backBtn);

 

So there we are adding the Frame values to our Button, where as I’m setting the width to a quarter of the Screen width, and as of the Height, I’m retrieving the NavigationBar’s height for it.

Next we need to add our UIButton to a UIView container as show above and make sure it has the same Height and Width as our UIButton.

Time to wrap things up fellas…

// A dummy button item to push our custom  back button to
// the edge of screen (sort of a hack)
var fixedSpace = new UIBarButtonItem(UIBarButtonSystemItem.FixedSpace)
{
	Width = -16f
};
// wrap our custom back button with a UIBarButtonItem
var backButtonItem = new UIBarButtonItem("", UIBarButtonItemStyle.Plain, null)
{
	CustomView = backBtn
};

// Add it to the ViewController
NavigationController.TopViewController.NavigationItem.LeftBarButtonItems 
= new[] { fixedSpace, backButtonItem };

 

So here’s the final steps, we are wrapping our button’s uiview container inside the UIBarButtonItem by setting it to the CustomView property. And then add it to the LeftBarButtonItems , which overrides the default existing Back Button.

Now you may wonder why there’s another UIBarButtonItem with the Width set to -16 value, this is actually to forcefully push our custom back button to the edge of the Navigation Bar. 😀 So that right, it is more of a hack to get the job done… 😉

See it in action…

So here’s our Custom iOS Back Button in action… 😀

screen-shot-2017-03-02-at-12-16-10-pm

Just for the sake of comparing here’s the default system Back Button in iOS…

screen-shot-2017-03-02-at-12-15-54-pm

Looks almost identical yeah! 😀

Well, that’s it fellas!

Enjoy! 😀

PS: I may have gotten some help from these posts on StackOverflow:

http://stackoverflow.com/questions/18384488/ios-7-uibarbutton-back-button-arrow-color
http://stackoverflow.com/questions/227078/creating-a-left-arrow-button-like-uinavigationbars-back-style-on-a-uitoolba