Tag Archives: Xamarin iOS

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!

Advertisements

Build yo own awesome Activity/Loading Indicator Page for Xamarin Forms…

Have you ever wanted to have an Activity or Loading indicator dialog screen overlay, that is transparent, and fully customized by you? in your Xamarin.Forms project?

Then you stopped at the right place.

Today I’m gonna share how to build a fully customizable Activity Indicator /Loading Screen from Xamarin.Forms with a bit of native magic. To be honest, more of a continuation of my previous blog post! 😉 lol

Perks:

  • Fully customizable View on the go from Xamarin.Forms
  • Overlays on top of your ContentPage / Navigation Stack
  • Service based, full MVVM & testing friendly
  • Fully transparent and controllable dimmer
  • Cancellation & back button disabled

Here’s a sneak peek…

  

TADAAA! That’s what yol gonna build! 😀

The Concept…

So basically if you think about it, when you want to display an Loading/Activity indicator overlay screen, it is something that would indicate,

“Oh there’s some important processing going on that Page and we need you to wait until it finishes…” 😛

“In the meantime we’re going to block the interactivity of that Page with this overlay, but you can still see the progress of it with the transparency…”

So in the language of Xamarin.Forms, on top of your ContentPage, we need something that would block the interactivity of background content but allows us to see what’s going in the background, in other words, it should be a transparent or dimmed View. 😀

A ghost from the past…

So I’m going to revert your attention to the previous blog post I wrote, Build your own Transparent Page from scratch for Xamarin.Forms, which was all about creating a Transparent page for Xamarin.Forms using a bit of native code. And I’ll be using the same concept and the code here as well, but I’m not going to drill down to the technical details of that specific implementation here, so if you’re looking for it, go ahead and give it a read first and come back.

The Recipe time…

So if you’re coming back  from my previous blog post you could probably consider this post as a continuation of it. Today we’re going to create a Transparent Page in Xamarin.Forms using a bit of native magic, that will overlay on top of any Xamarin.Forms ContentPage or the Navigation Stack, and has the capability to customize the Transparent content view on demand. 😀

So to do this, we’re going to implement a native Transparent page in our Platform projects (iOS and Android), then we’re going to create a Service implementation that can display and dismiss our Transparent pages on demand while being able to pass in the desired Content View as we wish to display as parameters. The actual concrete implementation of that service will bed laid down in platform specific projects, along side the native Transparent page rendering implementation. So that we can do the rendering or displaying or dismissing our Loading/Activity indicator overlay on demand as we wish.

So to map the Service interface and its concrete implementations we are going to use Xamarin.Forms Dependency service, but then if you have your own IoC container you could use it as well. 😉

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

Xamarin.Forms bits…

Alright then let’s hit it with the Service interface implementation. Let’s call it ILodingPageService.

public interface ILodingPageService
{
	void InitLoadingPage
                  (ContentPage loadingIndicatorPage = null);

	void ShowLoadingPage();

	void HideLoadingPage();
}

 

So we will have three interface methods, one to initiate and prepare the Transparent page we’re going to display as our Loading/Activity indicator overlay. Then two more to Show it or Hide it on the app.

Speaking of InitLoadingPage() method, the reason we need is to facilitate the feature of displaying different Loading pages or designs on demand at the run time. So let’s say in Page 1 we want to display one Loading page, then in Page 2 we want to display a different kind of Loading Page, that right there is possible here with this method. You just pass in whatever the Loading Page design you want to show, and you’re done! 😉 How cool is that!

Since this a Xamarin.Forms Transparent Page, let’s first create our usual ContentPage, with usual stuff. Let’s call it the LoadingIndicatorPage1

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="XFLoadingPageService.LoadingIndicatorPage1"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    BackgroundColor="#80000000">
    <ContentPage.Content>
        <StackLayout
            Padding="30"
            BackgroundColor="Black"
            HorizontalOptions="Center"
            VerticalOptions="Center">
            <ActivityIndicator IsRunning="True" Color="White" />
            <Label
                FontAttributes="Bold"
                Text="Loading..."
                TextColor="White" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

 

So you can see we have a very simple ContentPage design, with an ActivityIndicator and a Label to show that, “Oh look it’s a loading screen… boo!” lol 😀

Android bits….

Here come the actual magic, let me begin with Android! So let’s start off with our ILoadingPageService’s concrete implementation for Android and register it with the Xamarin Dependency Service.

[assembly: Xamarin.Forms.Dependency(typeof(LodingPageServiceDroid))]
namespace XFLoadingPageService.Droid
{
    public class LodingPageServiceDroid : ILodingPageService
    {
        private Android.Views.View _nativeView;

        private Dialog _dialog;

        private bool _isInitialized;

        public void InitLoadingPage(ContentPage loadingIndicatorPage)
        {
            // check if the page parameter is available
            if (loadingIndicatorPage != null)
            {
                // build the loading page with native base
                loadingIndicatorPage.Parent = Xamarin.Forms.Application.Current.MainPage;

                loadingIndicatorPage.Layout(new Rectangle(0, 0,
                    Xamarin.Forms.Application.Current.MainPage.Width,
                    Xamarin.Forms.Application.Current.MainPage.Height));

                var renderer = loadingIndicatorPage.GetOrCreateRenderer();

                _nativeView = renderer.View;

                _dialog = new Dialog(CrossCurrentActivity.Current.Activity);
                _dialog.RequestWindowFeature((int)WindowFeatures.NoTitle);
                _dialog.SetCancelable(false);
                _dialog.SetContentView(_nativeView);
                Window window = _dialog.Window;
                window.SetLayout(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent);
                window.ClearFlags(WindowManagerFlags.DimBehind);
                window.SetBackgroundDrawable(new ColorDrawable(Android.Graphics.Color.Transparent));

                _isInitialized = true;
            }
        }

        public void ShowLoadingPage()
        {
            // check if the user has set the page or not
            if (!_isInitialized)
                InitLoadingPage(new LoadingIndicatorPage1()); // set the default page

            // showing the native loading page
            _dialog.Show();
        }

        public void HideLoadingPage()
        {
            // Hide the page
            _dialog.Hide();
        }
    }
}

 

Most of the above Xamarin Android specific code is already explained in detailed line by line in my previous post. So in short, here we have the concrete implementation of our service for Android, inside the InitLoadingPage() we’re passing in the Xamarin.Forms Page which we want to render as a transparent page which will act as our Activity Indicator.  Then we’re rendering that page and embed into a Android Dialog view with a transparent background, and back button cancelled properties enabled. We’re keeping a reference of the _dialog instance so that we can show or hide the Page upon respective ShowLoadingPage() and HideLoadingPage() executions.

So every time a user wants to display a different Loading page, they will call the InitLoadingPage() which will build the new page instance and keep it in the service memory.

At the same time you may have seen inside ShowLoadingPage() if you haven’t instantiated the transparent page, then we’re using a default page, LoadingIndicatorPage1 as a template ad instantiating it on the go, just to avoid exceptions. This choice of default page is totally up to you.

Also don’t forget at the top of the namespace we’re registering this concrete implementation with Xamarin Dependency service. 😉

iOS bits….

Then let’s move on with our ILoadingPageService’s concrete implementation for iOS and register it with the Xamarin Dependency Service.

[assembly: Xamarin.Forms.Dependency(typeof(LodingPageServiceiOS))]
namespace XFLoadingPageService.iOS
{
    public class LodingPageServiceiOS : ILodingPageService
    {
        private UIView _nativeView;

        private bool _isInitialized;
        
        public void InitLoadingPage(ContentPage loadingIndicatorPage)
        {
            // check if the page parameter is available
            if (loadingIndicatorPage != null)
            {
                // build the loading page with native base
                loadingIndicatorPage.Parent = Xamarin.Forms.Application.Current.MainPage;

                loadingIndicatorPage.Layout(new Rectangle(0, 0,
                    Xamarin.Forms.Application.Current.MainPage.Width,
                    Xamarin.Forms.Application.Current.MainPage.Height));

                var renderer = loadingIndicatorPage.GetOrCreateRenderer();

                _nativeView = renderer.NativeView;

                _isInitialized = true;
            }
        }

        public void ShowLoadingPage()
        {
            // check if the user has set the page or not
            if (!_isInitialized)
                InitLoadingPage(new LoadingIndicatorPage1()); // set the default page

            // showing the native loading page
            UIApplication.SharedApplication.KeyWindow.AddSubview(_nativeView);
        }

        public void HideLoadingPage()
        {
            // Hide the page
            _nativeView.RemoveFromSuperview();
        }
    }
}

 

So the implementation here is also similar to Android code above, except for the native bit. So we’re instantiating the Xamarin.Forms Page instance inside, InitLoadingPage() method we’re initiating the transparent page instance and holding inside the service.

Then showing it or hiding it based on the ShowLoadingPage() or HideLoadingPage() calls.

Pretty straightforward eh! 😀

So what next…

Now one of the best features of this implementation is that your could use any number of Loading Indicator Pages as you wish with various kinds of designs. 😀 So just for the kicks of it here’s another page that we’ll use. let’s call it LoadingIndicatorPage2

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="XFLoadingPageService.LoadingIndicatorPage2"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    BackgroundColor="#80000000">
    <ContentPage.Content>
        <StackLayout
            Padding="30"
            BackgroundColor="#D93463"
            HorizontalOptions="Center"
            VerticalOptions="Center">
            <ActivityIndicator IsRunning="True" Color="White" />
            <Label
                FontAttributes="Bold"
                Text="Yo! Hold on..."
                TextColor="White" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

 

If that’s not enough you can add more and more as you go 😀 but just make sure to call the InitLoadingPage() method! 😉

Let’s fire it up…

So to fire this up we need to call this service from your Xamarin.Forms code using the DependencyService.

// show the loading page...
DependencyService.Get<ILodingPageService>()
                 .InitLoadingPage(new LoadingIndicatorPage1());
DependencyService.Get<ILodingPageService>().ShowLoadingPage();

 

There we’re first initiating our page and then show it on the app. Once you initiate the page you don’t have to call it ever again as you saw in the implementation, it is retained in the memory of the service.

// close the loading page...
DependencyService.Get<ILodingPageService>().HideLoadingPage();

 

Once you’re done, you can close our awesome Activity / Loading Indicator Page with the above code.

And here we go on iOS and Android in action…. 😀

That’s our first Loading screen in action…

And click on the second button, there’s our second Loading screen in action, on the go…

Look at that, even during navigation between pages our Loading page stays intact on top of the Xamarin.Forms Pages stack. 😉

The reason why it acts so independently is because we are directly accessing the native elements in the service implementation, therefore even during navigation of Xamarin.Forms Stack or whatever the UI activity our Loading page will not be affected, it will keep on, of its own.

How awesome is that eh! 😀

Github it if yo lazy!

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

Now your own imagination is the limit for what’s possible or not fellas!

That’s it for today.

Cheers! 😀

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! 😀

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

Animate a CATextLayer in Xamarin iOS

So this is a flash post about animating CATextLayer text color, or in descriptively animating ForegroundColor property of CATextLayer. 🙂 With Xamarin iOS!

Since this is a flash post I’m not going to explain what is CALayers or Core Animations of Xamarin iOS, rather let’s just jump into the code.

Using CABasicAnimation

Here’s the code…

// animate text color with CABasicAnimation
CABasicAnimation myCAbasicAnimation = CABasicAnimation.FromKeyPath("foregroundColor");
myCAbasicAnimation.SetFrom(UIColor.Blue.CGColor);
myCAbasicAnimation.SetTo(UIColor.Purple.CGColor);
myCAbasicAnimation.FillMode = CAFillMode.Forwards;
myCAbasicAnimation.Duration = 1.0f;
myCAbasicAnimation.RemovedOnCompletion = false;

// Add the animation to your CATextLayer
_myCAtextLayer.AddAnimation(myCAbasicAnimation, null);

 

So we basically set the FromKeyPath value which is the key value string for the property you want to target in your CATextLayer, in this case the “foregroundColor” as in the Text color.

Then we set the SetFrom and SetTo values, respectively the values to be animated in between. 🙂

Then if you want to remove this animation from your CATextLater upon completion, you could set the RemovedOnCompletion property to be true. Finally add the animation to your CATextLater by calling AddAnimation() and pass in the CABasicAnimation we just created. 😀

If you want to repeat and even reverse this animation, or put it in a loop, then use the below properties. 😉

myCAbasicAnimation.AutoReverses = true;
myCAbasicAnimation.RepeatCount = Single.PositiveInfinity;

 

TADAAAA! 😀

Using CATransaction

Here’s the code…

// animate text color with CATransaction
CATransaction.Begin();
// you could set CATransaction values by the key
CATransaction.SetValueForKey(new NSNumber(1.0f), CATransaction.AnimationDurationKey);
// or you could directly use properties AnimationDuration
//CATransaction.AnimationDuration = 1.0f;
_myCAtextLayer.ForegroundColor = UIColor.Purple.CGColor;
CATransaction.Commit();

 

This rather is rather good for animating a whole group of layers or animatable properties at the same time as an animation block. CATransactions are explicit where as you begin the modification layer upon Begin() call and finishes up on Commit() call.

That’s it. 😉

I guess in future I would be posting more of these “Flash Posts”, instead of lengthy explanatory articles due to work stuff. 😦 Hope for the best! 😀

How to add a fixed Background Image for a UIScrollView?

So recently I wanted to add a Fixed image behind a ScrollView in Xamarin Forms. Furthermore when the ScrollView is scrolling the background image shouldn’t scroll along with it, and background image should stay fixed while the content is scrolling.

Solution?

So the obvious solution would be to lay down a RelativeLayout and top of that Image, and then a ScrollView with Transparent background.

But I wanted…

but instead of laying out all those layouts and multiple controls, I wanted to achieve this right from one Control, by customizing the ScrollView accordingly.

So I got to into Coding…

So I created a Custom ScrollView control in PCL project and added the Custom Renderers for each platform iOS and Android. Although I got it working with ease in on Android by setting the Image as the Background drawable for the ScrollView, I was having some struggle with iOS.

trouble with iOS UIScrollView…

So the Xamarin Forms ScrollView’s native iOS mapped control is the UIScrollView. So I tried adding the a UIImageView to the UIScrollView from the custom renderer hoping it should get the job done according to theory.

but the background was panning across the Content size. And it started scrolling alone with the Content.

So let me walk you through what I tried and what actually worked… 🙂

1. Adding the UIImageView as a SubView

So as per the obvious solution I added the UIImage into a UIImageView and added it into the UIScrollView as a SubView as shown below. Also you may have noticed how I have called SendSubviewToBack method to place the UIImageView behind the UIScrollView.

protected override async void OnElementChanged(VisualElementChangedEventArgs e)
{
	base.OnElementChanged(e);

	if (e.NewElement != null)
	{
		var _uiImageViewBackground = new UIImageView(_uiImageBackground);

		this.AddSubview(_uiImageViewBackground);
		this.SendSubviewToBack(_uiImageViewBackground);
	}
}

 

And this was the result as you can see below..

method1

As you can see the UIImageView takes up the Height of the UIScrollView Content, not the UIScrollView actual Height, thereby resulting of the UIImageView spanning across the whole Content size. :O

2. Resizing the UIImage and adding the UIImageView as a SubView

Then I thought what if I resized the Image to the actual Height and Width of the UIScrollView and added as a Subview as show below.

Now in an iOS Custom Renderer we can not access the UIScrollView’s Bounds or Frame right from the OnElementChanged method, we need to override the Draw() method, which provides the Height and Width since it’s actually being drawn on the Parent view.

public override void Draw(CGRect rect)
{
	base.Draw(rect);

	// resize the UIImage to fit the current UIScrollView's width and height
	_uiImageBackground = ResizeUIImage(_uiImageBackground, (float)rect.Width, (float)rect.Height);

	var _uiImageViewBackground = new UIImageView(_uiImageBackground);

	this.AddSubview(_uiImageViewBackground);
	this.SendSubviewToBack(_uiImageViewBackground);
}

 

So as you can see I have resized the UIImage and added it to the UIScrollView thought a UIImageView holder.

Look at the results…

method2

Well the Background Image has been resized but the Background View still scrolls with the Content of UIScrollView. 😦

3. How about InsertSubview() ?

There are couple of methods for Adding a SubView to a View, the most common used one is the AddSubView() method which is also an alias for Add().

Then there also another method call we could use, InsertSubview(). In theory it does the same thing as AddSubView() but in a different manner where you could define a View index, in terms of which index the View should be added to in the array of sub-views in the given View.

So instead of this,

this.AddSubview(_uiImageViewBackground);
this.SendSubviewToBack(_uiImageViewBackground);

 

Let’s call the below, as you can see I’m placing our UIImageView at the very bottom of the SubViews stack by giving index 0 value.

this.InsertSubview(_uiImageViewBackground, 0);

 

Oh well what did you expect! Same result as before. 😦

4. How about InsertSubviewBelow() ?

So this method is also somewhat similar to above, where as this allows you to straightaway as a Subview, and define underneath which SubView you need to add your View in the stack. 😀

So I tried this as well. By the “this” reference I’m referring to the UIScrollView as the sibling and to tell the layout engine to place the UIImageView below the UIScrollView. 🙂

this.InsertSubviewBelow(_uiImageViewBackground, this);

 

But unfortunately the results was the same… 😦

5. What about directly setting the Background?

Frustrated with trying to add SubViews approach, I thought of directly setting the Background property of UIScrollView, specifically set the UIImage directly to the BackgroundColor Property of UIScrollView.

Well there’s no way we could set the BackgroundColor property from the Draw() method override, hence the canvas is already drawn. So we need to set it before its being drawn.

So let’s move back to the OnElementChanged method and set the BackgroundColor.

Since there’s no availability of the Height and Width values within the OnElementChanged event firing, for now we’ll just directly set the UIImage to BackgroundColor without resizing.

protected override async void OnElementChanged(VisualElementChangedEventArgs e)
{
	base.OnElementChanged(e);

	if (e.NewElement != null)
	{
			this.BackgroundColor = UIColor.FromPatternImage(_uiImageImageBackground);
	}
}

 

Oh well, look at the results. It also fills up the whole Content area, without just setting the “background” on UIScrollView.

method3

5. What about directly setting the Background with resized UIImage?

Alright now let’s get a bit serious and retry the above approach properly, by accessing the Height and Width of the UIScrollView and resizing the UIImage accordingly.

So to do this we need to tap into the place where the Height and Width first gets allocated before the Draw method. That’s by subscribing to the OnPropertyChanged() as shown below.

protected override async void OnElementChanged(VisualElementChangedEventArgs e)
{
	base.OnElementChanged(e);

	if (e.NewElement != null)
	{
		((CustomScrollView)e.NewElement).PropertyChanged += OnPropertyChanged;
	}
}

private void OnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
	if (propertyChangedEventArgs.PropertyName == CustomScrollView.HeightProperty.PropertyName)
	{
		// check if the Width and Height are assigned
		if (((CustomScrollView)sender).Width > 0 & ((CustomScrollView)sender).Height > 0)
		{
			// resize the UIImage to fit the current UIScrollView's width and height
			_uiImageImageBackground = ResizeUIImage(_uiImageImageBackground, (float)((CustomScrollView)sender).Width, (float)((CustomScrollView)sender).Height);

			// Set the background Image
			this.BackgroundColor = UIColor.FromPatternImage(_uiImageImageBackground);
		}
	}
}

 

So inside the OnPropertyChanged() event we are waiting till the Width and Height properties are available, as you can see we are looking for the PropertyName in the event args. Then we resize the UIImage according to the retrieved Height and Width and values of UIScrollView and set the UIImage to the Background.

method4

Now as you can see, the Background Image gets resized to the exact size of UIScrollView but the Background is still scrolling with the content. And if you notice closely, you can see the Background has repeated the Image, this is because of the UIColor.FromPatternImage() where as the UIImage gets repeated to fill the whole canvas. This means that the Background still gets spread across the whole Content area of the UIScrollView.

then I witnessed something strange….

What actually worked… (strangely though)

So meanwhile playing around with different override methods and properties, at some point….

I accidentally left the Draw() method overridden in my Custom Renderer as shown below, and moved the setting of the UIScrollView Background to the OnPropertyChanged event like I did in the previous step.

protected override async void OnElementChanged(VisualElementChangedEventArgs e)
{
	base.OnElementChanged(e);

	if (e.NewElement != null)
	{
		((CustomScrollView)e.NewElement).PropertyChanged += OnPropertyChanged;
	}
}

private void OnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
	if (propertyChangedEventArgs.PropertyName == CustomScrollView.HeightProperty.PropertyName)
	{
		// check if the Width and Height are assigned
		if (((CustomScrollView)sender).Width > 0 & ((CustomScrollView)sender).Height > 0)
		{
			// resize the UIImage to fit the current UIScrollView's width and height
			_uiImageImageBackground = ResizeUIImage(_uiImageImageBackground, (float)((CustomScrollView)sender).Width, (float)((CustomScrollView)sender).Height);

			// Set the background Image
			this.BackgroundColor = UIColor.FromPatternImage(_uiImageImageBackground);
		}
	}
}

//We need to override this to have the background image to be fixed
public override void Draw(CGRect rect)
{
	base.Draw(rect);
}

 

As you can see in my above code, I have just overriden the Draw() event and left it just as it is, without writing any code inside the method.

And behold! 😀 IT WORKED! 😀

bloopscrollview-on-ios-lowq

TADAA! 😀 as you can see we have successfully got it to work, a fixed background image in UIScrollView. 😉

Although this does not make any sense, how could the Background of the UIScrollView prevents itself from scaling to the size of Content size just by simply overriding the Draw() event, without even executing any code inside of it.

Either way this trick got the work done. 😀 May be this is just a bug in Xamarin or iOS. 😛

There you have it, how to add a fixed background image to a UIScrollView from custom renderer in Xamarin! 🙂

Enjoy!

Want to play a Vimeo Video in your Xamarin iOS app ? ;)

Remember my previous article on Let’s add a Video Stream Player to your Xamarin iOS App… ? 😀 Do you remember? If not check it out! It’s pretty cool! 😛

Anyways have you ever wanted to play a Vimeo video in your app? 😉 Question is probably yes and if you were redirected from Google, then you are already looking for it. lol 😀

The first time my boss asked me to do this, I was like.. huh? O.o Vimeo videos are played by streaming directly from their servers, how am I suppose to implement that in a mobile app, unless they have any 3rd party library, or adopt a bad practice such as implementing a web view to display the video with an embedded frame in it.

Yes it is a common requirement to attach an online video to your mobile app, such as from streaming giants as Youtube, Vimeo and etc. And for most of them have many third party libraries to consume their services such as streaming those videos, but only for native Mobile development.

But… what about Cross-Platform? ummm… Xamarin?  😦

Well it’s not impossible, there’s always a way! 😉

So today I’m gonna show you how you could play a Vimeo video in your Xamarin App.

First of all, if you haven’t implemented the Video player for your Xamarin app, then you may do as I did,  Let’s add a Video Stream Player to your Xamarin iOS App (but that’s for Xamarin iOS) and you could find a tutorial for Xamarin Android right here,Video player implementation for Xamarin Android.

Little something about Vimeo Videos…

When you consider a Vimeo video, it surely has the capability for streaming…

And also you could retrieve a static endpoint of the actual Video Source with extension.

but in order to retrieve you need to be the administrator of the account that posted this video. So this URL endpoint is what we are going to be using for our Video Player.

In my situation I had to play the Vimeo video which was posted by an account which I had the administrator access. But I couldn’t find if there’s any other ways to retrieve the static endpoint url for the video without having admin access to the Video you need to play.
So keep in mind it is crucial you have the admin access for the Vimeo account which had posted the video.

So how?

First log into your Vimeo account. Go to the Video you want to be played in your Mobile App. Click on the “Settings” button at the bottom of the video, in order to access Settings.

vimeo1

Once you’re in the Settings section of that video, click on the “Video File” tab.

vimeo2

Which will take you to the properties of the actual Video file of your Vimeo Video. Now pay attention to the bottom of the page here, where you’ll notice the “Access your Video files” section.

vimeo3

Yep right there is your savior, which will provide you with the endpoint URL with the extensions for your video, specially in different kinds of quality, HD or SD or even Live Streaming link.

So for our requirement we are going to be using the High Definition or the Standard Definition, based on your choice. Go ahead and copy the URL and use it as the Video source for your Video Player implementation in Xamarin. 🙂

vimeo4

Well that’s it! Simple as that! 😉

Hope this helped someone not to waste hours and hours by trying to implement WebView Embedded player for playing a simple Vimeo Video. 🙂

Cheers! 😀

Let’s add a Video Stream Player to your Xamarin iOS App…

So you wanna add an Online Video Player for your Xamarin iOS app ? How hard could it be, just add a WebView and screw up the whole thing right ? 😉 lol
Stream an online video? from Youtube? Vimeo? or wherever?

Yep one day I was given a task by my boss to implement a Video Player in one of our Xamarin iOS apps, that could play an online video…

So basically our app should be able to play an online video within the application frame. Add a Video Player control to the Xamarin iOS app but it should have all the controls with in the page itself, and more specifically this Video Player should be able to play Online Video, as in should be able to stream an Online Video over the internet. :O

Solution ?

After going through the Xamarin documentation, to my surprise I found out about this control that Xamarin provides called MPMoviePlayerController, which is like a built in controller for playing Videos, but in their documentation they had shown only an example of how to play a ‘locally stored video file’. Seriously? Who would wanna store a video file locally nowadays? 😛 lol

Anyhow, with a bit of uncertainty, I implemented this control, and after a bit of a struggle, I finally got it to working! 😀

So as usual, here I am sharing my experience with you guys… Hold on tight, it’s about to get bumpy! 😉

How to implement…

So basically we need to create an instance of the MPMoviePlayerController as follows, to be able to access it from any other methods in our ViewController, so that we could control the actions of the MPMoviePlayerController.

public class BlahBlahViewController : UIViewController
{
	MPMoviePlayerController moviePlayer;

	public BlahBlahViewController()
	{

	}
}

 

Next let’s go ahead with the implementation of the MPMoviePlayerController

// first define the Online Video URL you want to play 
var urltoplay = new NSUrl("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
moviePlayer = new MPMoviePlayerController();
// set the URL to the Video Player
moviePlayer.ContentUrl = urltoplay;
moviePlayer.View.Frame = new CGRect(55, 170, 310f, 200f);
// Set this property True if you want the video to be auto played on page load
moviePlayer.ShouldAutoplay = false;
// If you want to keep the Video player on-ready-to-play state, then enable this
// This will keep the video content loaded from the URL, untill you play it.
moviePlayer.PrepareToPlay();
// Enable the embeded video controls of the Video Player, this has several types of Embedded controls for you to choose
moviePlayer.ControlStyle = MPMovieControlStyle.Embedded;

View.AddSubview(moviePlayer.View);

 

As you can see above, this MPMoviePlayerController a lot of flexible customization and features for us to implement. Notice that PrepareToPlay() method will set the Video Player in a ready state to play the video on click. (It’s actually a nice option).
Also keep a note that you could choose any type of ControlStyle as you like as it provides a several options for the embedded controls of the Video Player.

Keep in Mind…

When you provide the Online Video URL to the control, make sure that URL has a video file extension for it. Otherwise this will not work, hence it requires the file extension for the video to be played. This control does not support direct Youtube or Vimeo video playing with their web browser link, you need to provide the online FTP location of the video to be played. 🙂

A little Cherry on top…

Now to put some cherry on top of the basic implementation I added some extra functionality by adding few custom buttons to control the Video Player implementation.

var playButton = UIButton.FromType(UIButtonType.RoundedRect);
playButton.Frame = new CGRect(10, 380, View.Bounds.Width - 20, 44);
playButton.SetTitle("Play Video", UIControlState.Normal);
playButton.BackgroundColor = UIColor.White;
playButton.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
playButton.TouchUpInside += delegate
{
	moviePlayer.Play();
};
View.AddSubview(playButton);

var playFullScreenButton = UIButton.FromType(UIButtonType.RoundedRect);
playFullScreenButton.Frame = new CGRect(10, 420, View.Bounds.Width - 20, 44);
playFullScreenButton.SetTitle("Play Full Screen Video", UIControlState.Normal);
playFullScreenButton.BackgroundColor = UIColor.White;
playFullScreenButton.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
playFullScreenButton.TouchUpInside += delegate
{
	moviePlayer.Play();
	// To play full screen
	moviePlayer.SetFullscreen(true, true);
};
View.AddSubview(playFullScreenButton);

var stopButton = UIButton.FromType(UIButtonType.RoundedRect);
stopButton.Frame = new CGRect(10, 460, View.Bounds.Width - 20, 44);
stopButton.SetTitle("Stop Video", UIControlState.Normal);
stopButton.BackgroundColor = UIColor.White;
stopButton.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
stopButton.TouchUpInside += delegate
{
	moviePlayer.Stop();
};
View.AddSubview(stopButton);

var pauseButton = UIButton.FromType(UIButtonType.RoundedRect);
pauseButton.Frame = new CGRect(10, 500, View.Bounds.Width - 20, 44);
pauseButton.SetTitle("Pause Video", UIControlState.Normal);
pauseButton.BackgroundColor = UIColor.White;
pauseButton.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
pauseButton.TouchUpInside += delegate
{
	moviePlayer.Pause();
};
View.AddSubview(pauseButton);

 

There you have it, a four button implementation for controlling the Video playing of MPMoviePlayerController.

As you may have noticed in the ‘Play Full Screen Video’ button action, I have called the method moviePlayer.SetFullscreen(true, true); which allows us to play the video in full screen mode. Once the click even fires, the Video controller will nicely stretch itself to the fullscreen of the app and play the video.

Alright, now let’s see how this actually looks after the implementation.

Here’s how it’ll look like… 😀

hustle hustle (1)

there you everyone, now go crazy with it. 😉

Here’s something extra…

Did you know you could detect the state changes in the MPMoviePlayerController and control its behavior ? Yes MPMoviePlayerController has a set of Observable notification methods that we could register and use for our own needs as follows.

// Register yourself for the observable notifcations
MPMoviePlayerController.Notifications.ObservePlaybackStateDidChange(MediaPLayer_OnPlaybackStateDidChange);
MPMoviePlayerController.Notifications.ObservePlaybackDidFinish(MediaPLayer_OnPlaybackComplete);

.....

// And do whatever you want based on the events

// For and example here I'm automatically setting the player to the full screen  when it starts Playing
private void MediaPLayer_OnPlaybackStateDidChange(object sender, NSNotificationEventArgs e)
{
	if (moviePlayer.PlaybackState == MPMoviePlaybackState.Playing)
	{
		moviePlayer.SetFullscreen(true, true);
	}
}

// Another example, automatically exiting the full screen when the Play back completes
private void MediaPLayer_OnPlaybackComplete(object sender, MPMoviePlayerFinishedEventArgs e)
{
	moviePlayer.SetFullscreen(false, true);
	moviePlayer.View.Hidden = true;
}

 

Yep there you go another set of awesome features we could play around in MPMoviePlayerController.

Parallels Picture

There’s a whole set of Observable events you could register yourself to based on your requirements and to play around with! 😉

Cheers!

Stay awesome! 😀

Setting the NavigationBar colors in Xamarin.Android and Xamarin.iOS

WOOT! WOOT! This is regarding my previous post on Setting the NavigationBar colors in Xamarin.Forms!

So I thought it might be handy for some of you to know how to set the NavigationBar colors in Xamarin.Android and Xamarin.iOS! And oh, I’m not going to tell you about the reasons why you would ever want to do this and blah blah as I have mentioned that already in my previous post. lol 😛

When it comes to Xamarin Native level there’s a huge advantage with in-depth customization for any controllers and properties. Therefore some of you might want to dive into the custom renderers when you customize the Navigation Bar and so on. Or may be you are doing a development on native Xamarin.Android app or native Xamarin.iOS app, thereby you may be in need of customizing the NavigationBar (iOS) or the ActivityBar (Android) respectively. However the reasons, let’s get down to business.. 😀

NavigationBar Customization in Xamarin.iOS …. 🙂

Yes in iOS we refer to the NavigationBar just as it is, lol and you could easily customize it by referring to the UINavigationBar.Appearance property.
Here’s some sample customization you could do using these properties, but keep in mind you could constomize this very easily and in-detail according to your preferences, just a matter of a playing around 😉 

// Setting (NavigationBar) Toolbar background color natively
UINavigationBar.Appearance.BarTintColor = Color.FromHex("#ff5300").ToUIColor();
UINavigationBar.Appearance.TintColor = UIColor.White;
UINavigationBar.Appearance.SetTitleTextAttributes(
	new UITextAttributes { TextColor = Color.White.ToUIColor() });

 

ActionBar Customization in Xamarin.Android …. 🙂

Oh Yes! in Android we could refer to the ActionBar via the Context instance or may be if you are inside of an Activity, you could directly static reference it, to access its various Set properties for customization. Here also you could go in-detail according to your preferences, just a matter of a playing around 😉

// Setting ActionBar (Toolbar) background color natively
var actionBar = ((Activity)Context).ActionBar;
actionBar.SetBackgroundDrawable(new ColorDrawable(Xamarin.Forms.Color.FromHex("#ff5300").ToAndroid()));

 

WOOT! WOOT! There you go! 😀

Oh well just another tiny blog post in a boring day I guess.. lol

Cheers!

Stay Awesome! 😀

 

Setting the NavigationBar colors in Xamarin.Forms

Have’t you ever got bored of the default colors of the Navigation bar of your applications ? 😛 Well I know I did, so as my boss in the new company I’m working for. lol

Enough chit chat! Lemme show you how to change the background color of the default Navigation bar in our awesome Xamarin Forms framework.

Yes it’s crazy simple nowadays, as Xamarin has allowed us to control that from the PCL level itself. But earlier I recall it was pretty complex where we had to write custom renderers and stuff.

How to… from C# code level ?

Xamarin has introduced the following properties for this job, BarBackgroundColor, and BarTextColor. You could easily set these properties for your NavigationPage instance and woahlah ! You are done.

public App()
{
	MainPage = new NavigationPage(new Page1())
	{
		BarBackgroundColor = Color.FromHex("#ff5300"),
		BarTextColor = Color.White,
	};
}

 

Alright now, hit Run and check it out fellas !

Behold…

Nexus 4 (Lollipop) Screenshot 1  Simulator Screen Shot 4 Feb 2016, 12.28.46 PM

Oh look at that gorgeous NavigationBar… Such an eye-candy view.. lol

Alright looks good… moving on… 😛

How to… from XAML code level ?

What if you wanted to set these properties in XAML level ? 😀

Well to tell you a little story, the project I’m working now is pretty complex and the architecture is super awesome, that we have to dive massively into MVVM and Architectural design stuff… So we usually keep all the UI related stuff in XAML level. 😉 So yeah this is how I originally implemented it, but I did the C# code stuff just to show the separation. End of Storytime ! lol 😛

So here’s how to handle this in XAML…

  <App.Resources>
    <ResourceDictionary>
      
      <!-- Styles -->
      <Style TargetType="NavigationPage">
        <Setter Property="BarBackgroundColor" Value="#ff5300"/>
        <Setter Property="BarTextColor" Value="White"/>
      </Style>
      <!-- Styles -->

	</ResourceDictionary>
  </App.Resources>

 

You simply put those values in your global Style level, so when the app is running it will fetch them from those values and set it to the navigation bar.

TADAAAAA ! 😀

That’s it… Cheers!

Stay Awesome developers !