Creating a HyperlinkLabel in Xamarin Forms

By | November 5, 2017

I needed a simple control that could show a hyperlink inline with other text and I’d like the link to be defined in markdown.
In short, something like this:

HyperlinkLabel

HyperlinkLabel

In Xamarin.Forms, I created a HyperlinkLabel class which isn’t anything more than a class inheriting from the standard Label with an additional bindable property RawText. It also has a method GetText  that parses the RawText  property using a RegexExpression. The method returns the text that eventually will get displayed (without the markdown). Through the out parameter, this method returns all info we need about all the links in the text: the text of the link, the url and the index where this link is positioned in the Text.

iOS

In order to get this in iOS, we both need a custom control and a Renderer.

HyperlinkUIView

A UITextView in iOS is able to render inline links, through the usage of a NSAttributedString. A NSAttributedString is a string with attributes… (Who would have thought that :-)). These attributes can define, for a particular range, all sorts of stuff like the font, color, … and whether a piece of text is a link. But a UITextView also has some standard behavior that I don’t want like the text being selectable. That’s why I created a custom control HyperlinkUIView that inherits from UITextView and overrides these behaviors. It also automatically sets its size to the size of the text.

HyperlinkLabelRenderer

This renderer on iOS will ‘translate’ the HyperlinkLabel to the HyperlinkUIView. There isn’t anything special going on in this class. In the SetText  method, we ask the Text that should be printed from the HyperlinkLabel. We loop over the links that we also get back from the HyperlinkLabel’s GetText method and we simple add the necessary attributes to the NSMutableAttributedString.

Please mind that I use Element.Font.ToUIFont() to get the UIFont from the Element. However, the Font property is deprecated, but for now it still works. As far as I know, there is no other way to easily translate the font attributes defined on a Xamarin Forms control to a UIFont. There is, however, an extension method in Xamarin Forms that does this: internal static UIFont ToUIFont(this Label label). But, as you can see, this method is internal, so we can’t use it in our own code and I didn’t feel like copy en pasting this code. Xamarin should just make this method public, right? 😉

UWP

There is no need for a custom control in UWP as a TextBlock already supports inline links. So the only thing we need is a custom renderer.

HyperlinkLabelRenderer

This class does more or less the same thing as its counterpart in iOS. But instead of working with attributed strings, we can put Runs and Hyperlinks inside a TextBlock. So we are basically going to chop our Text into pieces (‘pure’ text or links) and add them as a Run or Hyperlink respectively to the Inlines collection of our TextBlock.

Remarks

This is just a very basic implementation for iOS and UWP, I don’t have an Android version yet. Also, I don’t take every property that has been set on the Label into account (fontsize, color, … on UWP and other things as well). But please, if you need this stuff and feel like implementing it, my code is on GitHub and just do a PR! 🙂

 

Find the code on GitHub.

 

Remarks, questions? Just drop a comment and I’ll get back to you.

 

Leave a Reply