So I created a Popup with Transparent background in Xamarin Forms… ;)

Alright so I was supposed to post this few months back, before I got stuck with my day job which led to temporary put my blog on hold. Either way, recently I managed to find some free time off from work, so I would go ahead and post this with some necessary updates! 🙂

So a while back I was asked to create a Transparent popup control in Xamarin Forms, as ordered by my boss (a very cool guy) to be used for instances such as Loading Spinner screens, and Popup Dialog boxes.

Xamarin Forms ContentPage ? Transparency ?

So I tried to derive my custom control from the default ContentPage control of Xamarin Forms, by setting the Background color of the page to Transparent.

Although I’ve failed by pushing the Page to NavigationStack, I managed to get it working as a Modal page by pushing it to the ModalStack but only on Android platform.

Let’s get into coding…

Alright let’s get into some coding, first create the Custom Control by deriving from ContentPage.

    public class TransparentPopup : ContentPage
    {
        public TransparentPopup()
        {
            // set the background to transparent color 
            // (actually darkened-transparency: notice the alpha value at the end)
            this.BackgroundColor = new Color(0,0,0, 0.4);
        }
    }

 

Although this implementation worked out of the box on Android, it didn’t work as expected on iOS, probably due to the differences the page drawing process of Android and iOS, specially as a popup View.

So I played around with iOS and managed to get it working. So let’s create a custom renderer for iOS.

The deal here is to prepare the Popup to draw over the Parent View Controller which is the previous page. So that we could see through the Popup to see the page underneath which is the parent view. Becase in iOS when a new View Controller is introduced the previous View Controller’s View gets removed from the Window.

[assembly: ExportRenderer(typeof(TransparentPopup), typeof(TransparentPopupRenderer))]
namespace WhateverYourNamespace.iOS
{
    public class TransparentPopupRenderer : PageRenderer
    {
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);
        }

        public override void DidMoveToParentViewController(UIViewController parent)
        {
            base.DidMoveToParentViewController(parent);

            if (ParentViewController != null)
            {
                // Preparing the view to get the presentation of the parent view for the background
                ParentViewController.ModalPresentationStyle = UIModalPresentationStyle.OverCurrentContext;
            }
        }

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            // Setting the background color to transparent when the view is appearing
            View.BackgroundColor = UIColor.Clear;
        }
    }
}

 

DidMoveToParentViewController called when the current view gets added to the parent ViewController, so at that point we will set the ModalPresentationStyle of the parent controller, to OverCurrentContext property which will draw our popup view over the previous view.

Well that’s the iOS Custom Renderer, and like I mentioned before we are not going to be needing a Custom Rendering for Android, hence the Modal Page get’s drawn directly above the previous page view.

So let’s put it to use eh! 😉

 Navigation.PushModalAsync(new TransparentPopup());

 

Yep! that’s pretty much it. 🙂

Thou shalt grab em code up on my github: XFTransparentPopup

Cheers!

Wait for it……..

A journey through time…

*fast forwards time…*

*forwarding through time 4-6 months…*

*passing through them late night work hours at office…*

*days of procrastinating and laziness…*

*till this date (November, 2016)*

So after time travelling to this date I updated my local Xamarin installation and this project solution’s Xamarin references, hoping to refresh everything an finally finish off this article.

BOOM! EVERYTHING BROKEN!

Yep since the upgrade to the latest Xamarin references the above implementation has broken and transparency is working no more for the Modal Pages.

Hence it appears to be a change in the Xamarin Core implementation for ContentPage and the rendering process of Modal Pages with the latest update, there had been some other complaints in the Xamarin Forums regarding this. Although whatever the changes Xamarin Forms team has done, I’m sure they had their reasons. This seems to be occurring from all the new Xamarin versions, since I’ve been trying out few fresh Project solutions as well

Looks like I need to find an alternative (until I find a workaround)….

Alternative?

Very well… lucky enough I stumbled upon this awesome library called, Rg.Plugins.Popup! Which literally saved me tons of time. This is a Xamarin Forms library that allows you to create Transparent Popup pages, allowing you to open any ContentPage control as a popup page with full transparency background.

And this library solves a massive problem xamarin developers have been facing, which is the Transition animation control between pages, where as in default Xamarin Forms navigation stack, we can not modify the Transition animations between pages, but with this library, it’s all possible and we could add our own custom animations for page transitions.

capture

Go ahead visit their Github page for description: https://github.com/rotorgames/Rg.Plugins.Popup

Looks very promising indeed. Alright let’s try it out!

Praising le third party library…

Alright just for basics add the Rg.Plugins.Popup library to your Xamarin Forms project from Nuget.

This library provides us a base control that is called PopupPage, which gives you full Transparency background properties, therefore instead of deriving from ContentPage, now we are going to derive from PopupPage to our Transparent Page.

namespace WhateverYourNamespace
{
    public class TransparentPopup : PopupPage
    {
        public TransparentPopup()
        {
            // set the background to transparent color 
            // (actually darkened-transparency: notice the alpha value at the end)
            this.BackgroundColor = new Color(0, 0, 0, 0.4);
        }
    }
}

 

There you go, now let’s add some decorations to our Transparent Popup Page. 😉

public TransparentPopup()
{
	Button btnClose = new Button() { Text = "Close this" };
	btnClose.Clicked += BtnCloseOnClicked;

	Content = new StackLayout()
	{
		BackgroundColor = Color.Transparent,
		Children =
		{
			new Label()
			{
				Text = "Hello from Transparent Modal Page",
				FontSize = 18,
				TextColor = Color.White,
				HorizontalTextAlignment = TextAlignment.Center
			},
			new ActivityIndicator()
			{
				IsRunning = true
			},
			btnClose,
		},
		VerticalOptions = LayoutOptions.Center,
		Padding = new Thickness(10,0,10,0),
	};

	// set the background to transparent color 
	// (actually darkened-transparency: notice the alpha value at the end)
	this.BackgroundColor = new Color(0, 0, 0, 0.4);
}

private void BtnCloseOnClicked(object sender, EventArgs eventArgs)
{
	// Close the modal page
	PopupNavigation.PopAsync();
}

 

Alright, shotgun! There we have added a welcome Label, Activity indicator and a Button to close the popup.

Something important!

And as you can see on the BtnCloseOnClicked event, we are accessing a property called PopupNavigation, instead of default Xamarin Forms Navigation property, to remove the page from Stack.

Well its because Rg.Plugins.Popup maintains its own Popup-Navigation Stack which keeps references to the Popups of it’s own kind, which derives from the PopupPage. So we need to access that property to remove the page from our Navigation stack.

It also provides a Page background click behavior, which is if the user clicks on the background of the page, we could trigger an event to exit the page. Well in my case I didn’t want that to happen so let’s disable it. 😀

protected override bool OnBackgroundClicked()
{
	return false;
}

 

Alright, let’s consume this fella right now as below,

Navigation.PushPopupAsync(new TransparentPopup());

 

Now you must have expected to use the ordinary Navigation.PushModalAsync() as what we normally do in Xamarin Forms, yes of course you could do the same to open this Transparent Popup page, but you may loose the Transparency and ability to override the Navigation Transition animations.

Therefore we are using the PushPopupAsync() extension method that’s provided by this library, which is pretty cool. Now the reason for this I shall explain later in this post.

Alright! Let’s run this fella and see for ourselves! 🙂

nexus-5-lollipop-screenshot-1  simulator-screen-shot-6-dec-2016-10-46-02-am

WOOT! WOOT!

there you go! 😀

For You lazy people may fetch my code up on my githubXFTransparentPopupUpdate

Enjoy!

Important after-notes to share…

1. Page Transition Animations

In default Xamarin Forms Navigation we do not have the access to Page Transition Animations, hence we have to suck it up with the default boring Transition animations of Xamarin Forms.

But thanks to this library, Rg.Plugins.Popup maintains its own Popup-Navigation Stack which to allow us to control the Page Navigation Transition effects, unlike in default Xamarin Forms Navigation Stack. This is a great feature that is provided by this solution hence a lot of developers were having issues with this restriction of Xamarin Forms since long time back. 🙂

2. PushPopupAsync()

Also it is important to mention that, when using Popup pages of Rg.Plugins.Popup  we should always use the Navigation.PushPopupAsync() extension if we want to preserve the Transparency and Custom Page transition features. Meanwhile using the PopupNavigation.PopAsync() to remove the pages from the stack while maintaining transition effects. 😀

3. PushPopupAsync()

We are all aware of how on Android run time, Xamarin Forms uses a Single Activity to populate the Pages of our app. And usually when we add a Modal Page, it gets populated on top of the Single Activity the app is running on. But in this Library it uses a separate Android Dialog View which doesn’t use the Activity Stack, instead it draws itself over the Activity, (blocking the whole Activity content) such as in AndHUD library. So that’s something to keep in mind if you wonder why you couldn’t Push a Page on top of this popup page. 😉

Finally kudos to the developers of Rg.Plugins.Popup plugin for Xamarin Forms!

Advertisements

One thought on “So I created a Popup with Transparent background in Xamarin Forms… ;)

  1. Awesome post! I appreciate the update and alternative that you listed, and the tutorial as well. Many people really seem to like this plugin.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s