11

Xamarin forms – multi line label custom renderer gotcha

On a project I’m working on, we needed a label that would show an ellipsis at the end. ( the 3 … indicating there is more text but not enough space on the screen to fit it all )

Having this on a label control in Xamarin forms is easy, you just add the property

this will force the ellipsis to appear if needed.

But on a specific page we wanted to show more text to the end user and even than add an ellipsis if needed. So in other words we would love to be able to tell the label control how many lines it should at least try to display.
To get this working in Xamarin forms you’ll need to add a custom renderer. Because the Xamarin forms label control doesn’t have any property available for us to manipulate to accomplish this.

This is not difficult at all to do, but there is a small gotcha with Android when you want to pull this off!

But let’s start with what you need to do to get this working.
In the Xamarin forms PCL ( so the general one, not the iOS or Android project ), we first add a class called MultiLineLabel.cs – this will be our own custom control.
It inherits from Label and we only need to add 1 dependency property called Lines, defined as an int. It looks like this:

After defining this custom control, we can use it on our XAML page, like so:

We will be using this Lines property in our custom renderers.
First up the iOS custom renderer for our MultiLineLabel. Create a class in the Xamarin forms iOS project called CustomMultiLineLabelRenderer.cs with following code:

You’ll notice that we are checking if the user specified a value for the Lines dependency property and if this is true, we pass this to the actual iOS UIKit.UILabel control by setting it’s Lines property. With this in place we get following result.

Screen Shot 2016-06-27 at 08.31.08

So iOS is done and looking great. Now add the Android renderer. Create a CustomMultiLineLabelRenderer.cs class in the Xamarin forms Android project with following code:

This doesn’t look all that different from the iOS counterpart… instead of setting a property we now use a method SetLines on the Android.Widget.TextView indicating how many lines we want it to display.
But wait, if we try this and look at the result, we’ll notice that it doesn’t work!!

Screen Shot 2016-06-27 at 08.31.05

It took me a while to figure this out ( I’m no Android expert 😉 ). But after taking a look in the Xamarin forms source code ( glad it’s open source 😉 ) I noticed they will always force a SetSingleLine(true) when setting the TailTruncation LineBreakMode…
Code can be seen here https://github.com/xamarin/Xamarin.Forms/blob/2d9288eee6e6f197364a64308183725e7bd561f9/Xamarin.Forms.Platform.Android/Renderers/LabelRenderer.cs#L179

So the fix is easy… you need to reset this Single Line forcing, the final code looks like this ( in your custom renderer ) :

With that in place we’ll get following result

Screen Shot 2016-06-27 at 08.31.31

Yeah success!
To start I’ve done a pull request on Xamarin forms to counter this SingleLine forcing, but not sure this will be added though… https://github.com/xamarin/Xamarin.Forms/pull/234
So better be safe and add the extra line in your own custom renderer for now.

As always example project up on github here…

Depechie

11 Comments

  1. This helped me alot! Thank you very much!!
    But what about a solution for windows phones?

  2. Good question, I have to say I haven’t looked at that myself yet… Is it a problem on UWP and Windows Phone 8.1? Unable to add these projects on my MacBook Xamarin Studio

  3. At the moment I have only testet on Windows Phone 8.1
    I copied the renderer from iOS.
    It complains on the Line in: Control.Lines = multiLineLabel.Lines;
    error msg = ‘TextBlock’ does not contain a definition for ‘Lines’ and no extension method ‘Lines’ accepting a first argument of type ‘TextBlock’ could be found (are you missing a using directive or an assembly reference?)
    I’m very new to programming. :/ =)

  4. The property to limit the amount of lines on textblock is called MaxLines… try that?

  5. I changed the code to: Control.MaxLines = multiLineLabel.Lines;
    No more errors but it dosen’t work, the labels only show one line.

  6. Also try setting the Control.TextWrapping = TextWrapping.Wrap

  7. Hi
    I was just wondering, if it’d be also possible to create multiline labels in the c# source.

    Lets say the following code:

    MultiLineLabel ProductName = new MultiLineLabel()
    {
    FontSize = 12
    // BackgroundColor = Color.Red

    };
    ProductName.SetBinding(Label.TextProperty, “sName”);
    ProductName.LineBreakMode = LineBreakMode.TailTruncation;
    ProductName.Lines = 2;

    The Label shows up but doesnt have 2 lines.. I assume, thats because the custom render method is not been called.

    Do you know how that problem may be fixed?

    Thanks for the great post!

  8. Okay.. If I would have read some more lines, I would have seen the fix for android 😉
    Works perfect – Thanks again!

  9. That is weird, so long as the setup for the custom renderer is done right is should be called even if you add it through code

Leave a Reply

Your email address will not be published. Required fields are marked *