Untitled-1

So I created this AwesomeHyperLinkLabel custom renderer control one day for Xamarin Forms!

Have you ever wanted to create a Label that could automatically detect HTTP Web Links ? or Phone number text ? or EMail address text ? and enable clickable action only on top of those links in the Label ? 😉

Well it’s a very common scenario in Mobile Apps development, if you had experienced it already, you know its very easy in Native app development. But when it comes to Xamarin Forms, oh well it’s a different story, whereas people almost end up trying to implement a WebView control instead of the Label and complicate the whole situation. lol 😀 (Yes I have been there too) Well XFLabs have a clickable Label control, but who on earth would want to make an entire Label control clickable only for a specific set of text like an email address inside a label, unless your intension is to fill the whole label with the email address only. 😛

Anyhow there was this one time I wanted to create a Label which automatically detect HTTP Web URLs, Phone Number text, Email Address text and enables clickable actions only on top of those specific types of text.

Solution ?

Well if it’s impossible to do it in Xamarin Forms, of course we need to praise the Custom Renderers, just like I did in my scenario. So here goes my solution. We are going to create a Custom Control in Xamarin Forms, which is going to be overridden in native Level and adjust the control to our needs. And I’m gonna call it the “AwesomeHyperLinkLabel

PCL Implementation

So as usual, we create a custom control based on the Xamarin Forms Label as shown below…

namespace WhateverYourNamespace
{
    /// <summary>
    /// Automatically detects the Phone numbers, web links and email addresses
    /// and make them clickable to be opened up in default device applications
    /// </summary>
    public class AwesomeHyperLinkLabel : Label
    {

    }
}

 

Android Implementation

In Android we have the option property in default TextView called AutoLinkMask , which allows us to automatically set the TextView to detect and highlight all kinds of URLs, Phone Numbers, and EMail addresses.

[assembly: ExportRenderer(typeof(AwesomeHyperLinkLabel), typeof(AwesomeHyperLinkLabelRenderer))]
namespace WhateverYourNamespace
{
    public class AwesomeHyperLinkLabelRenderer : LabelRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
        {
            base.OnElementChanged(e);

            var view = (AwesomeHyperLinkLabel)Element;
            if (view == null) return;

            TextView textView = new TextView(Forms.Context);
            textView.LayoutParameters = new LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent);
            textView.SetTextColor(view.TextColor.ToAndroid());
            
	    // Setting the auto link mask to capture all types of link-able data
            textView.AutoLinkMask = MatchOptions.All;
	    // Make sure to set text after setting the mask
            textView.Text = view.Text;
            textView.SetTextSize(ComplexUnitType.Dip, (float)view.FontSize);

	    // overriding Xamarin Forms Label and replace with our native control
            SetNativeControl(textView);
        }
    }
}

 

So as you can see above I have overridden the Xamarin Forms control with our native TextView control. Make sure to set text after setting the AutoLinkMask, otherwise the link-able text would not be detected by the TextView. Also keep in mind here you could define specifically what types of link-able data you need the Label to detect based on your requirements. 😉 but above example I have set it to all.

iOS Implementation

Also in iOS, we could use DataDetectorTypes property on UITextView which allows us to do the same as above, but keep in mind in Xamarin iOS UILabel is the equivalent of Xamarin Forms Label, but UILabel doesn’t have such properties to support our scenario. So we have to move to the native UITextView control.

It’s very important to keep in mind due to the above reasons we cannot derive this Custom Renderer from the usual LabelRenderer, we need to use the common ViewRenderer.

[assembly: ExportRenderer(typeof(AwesomeHyperLinkLabel), typeof(AwesomeHyperLinkLabelRenderer))]
namespace WhateverYourNamespace
{
    public class AwesomeHyperLinkLabelRenderer : ViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<View> e)
        {
            base.OnElementChanged(e);

            var view = (AwesomeHyperLinkLabel)Element;
            if (view == null) return;

            UITextView uilabelleftside = new UITextView(new CGRect(0, 0, view.Width, view.Height));
            uilabelleftside.Text = view.Text;
            uilabelleftside.Font = UIFont.SystemFontOfSize((float)view.FontSize);
            uilabelleftside.Editable = false;
			
	    // Setting the data detector types mask to capture all types of link-able data
            uilabelleftside.DataDetectorTypes = UIDataDetectorType.All;
            uilabelleftside.BackgroundColor = UIColor.Clear;

	    // overriding Xamarin Forms Label and replace with our native control
            SetNativeControl(uilabelleftside);
        }
    }
}

 

So as you can see above we are setting the DataDetectorTypes property in UITextView to allow the control to highlight the link-able data. Also specially note that we are using ViewRenderer and overriding the Xamarin Forms Label with UITextView control.

That is why we have disabled the Editable property above and we are doing our best for this control to behave as a Label.

Let’s try it out!

Too bored to try it out yourself ? 😛 Yeah thought so. lol Anyways here’s a sample code where you could try out my AwesomeHyperLinkLabel.

public App()
{
	// The root page of your application
	MainPage = new ContentPage
	{
		Content = new StackLayout
		{
			VerticalOptions = LayoutOptions.Center,
			Padding = new Thickness(10, 0, 10, 0),
			Children = {
				new Label
				{
					Text = "Hello! This is normal Label!"
				},
				new AwesomeHyperLinkLabel {
					Text = "Hello! This is the AwesomeHyperLinkLabel by ÇøŋfuzëÐ SøurcëÇødë ! \n\nClick here www.confuzed-sourcecode.com and phone number : +65 9215 7231 and email address : udara.blahblah@blah.com"
				},
			}
		}
	};
}

 

Very well, there you go fellas, now hit F5 and run that thing… 😉

TADAAAA!

WOOT WOOT ! Here how it is in iOS and Android ! 😀

Simulator Screen Shot 8 Mar 2016, 2.09.12 PM Nexus 4 (Lollipop) Screenshot 1

Cheers!

Stay awesome fellas! 🙂

 

8 thoughts on “So I created this AwesomeHyperLinkLabel custom renderer control one day for Xamarin Forms!

  1. Hey Great Renderer ! Super Idea !

    It works great in very simple use.

    However it does not work if the text is not declared in the constructor or in the XAML.
    So I cannot use it since I am getting my text from a dataBase and displaying it after receiving the answer (AwesomeLabel.Texte = myObject.text in another method) 😦

    Any idea how to make it work so I can fill up the text, and change it when ever I want ?
    Thanks

    1. Thanks mate. Glad it helped.

      Well you could override the OnElementPropertyChanged event in the Custom Renderer level, to the detect text property changed event and set the native control’s text accordingly to that value. 🙂
      Good luck.

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