Xamarin.Forms Label controls do not have the capability to adjust their font size to accomodate the width of the content. You have to use a view renderer in the platform-specific project to accomplish this. This blog post shows how to customize a label control for use in XAML for the iOS platform.

Create the LabelWorld Application in Xamarin Studio

If you have any problems with the following steps, see Xamarin.Forms Quickstart.

  1. Launch Xamarin Studio. Find it in the Applications folder or via Spotlight.

  2. In Xamarin Studio, click New Solution…

  3. In the Choose a template for your new project dialog, click Cross-platorm App and then select the Xamarin.Forms App template.

  4. In the Configure your Xamarin.Forms App dialog, enter LabelWorld as your App Name. Leave iOS and Android Target Platforms checked. For Shared Code, select Use Portable Class Library.

  5. In the Configure your new project dialog, leave the Solution and Project names set to LabelWorld, choose a suitable location for the project, and then click the Create button.

  6. Run the app in the simulator by pressing the Start button (looks like a Play button):

Welcome to Xamarin Forms

Add a XAML Page

  1. In Xamarin Studio’s left-hand pane, Solution, click the gear icon next to the LabelWorld project and select Add > New File…

  2. In the New File dialog, select Forms > Forms ContentPage Xaml, name the new file LabelWorldPage, and click the New button. This will add a XAML page named LabelWorldPage to the project. This includes a XAML page:[sourcecode language=”xml”] <?xml version=”1.0” encoding=”UTF-8”?>

[/sourcecode]

and a partial class:

[sourcecode language=”csharp”] using System; using System.Collections.Generic;

using Xamarin.Forms;

namespace LabelWorld { public partial class LabelWorldPage : ContentPage { public LabelWorldPage () { InitializeComponent (); } } } [/sourcecode]

  1. Run the project. It look no different. We’ll fix that by replacing the contents of the App() method in the LabelWorld class.

  2. Edit the LabelWorld.cs file. Replace the contents of the App() method: [sourcecode language=”csharp”] using System; using Xamarin.Forms;

namespace LabelWorld { public class App : Application {

public App () { // The root page of your application MainPage = new LabelWorldPage(); }

protected override void OnStart () { // Handle when your app starts }

protected override void OnSleep () { // Handle when your app sleeps }

protected override void OnResume () { // Handle when your app resumes } } } [/sourcecode]

  1. Run the app again. Now you’ll get a blank screen in place of the “Welcome to Xamarin Forms!” label in the middle of the screen. Let’s fix that by adding a label to the XAML file.

  2. Replace the contents of the LabelWorldPage.xaml file to add four labels: [sourcecode language=”xml”] <?xml version=”1.0” encoding=”UTF-8”?>

[/sourcecode]

Notes: 1. iOS-specific Padding had been added to the ContentPage to prevent the first label from overlapping with the status bar.

3. You can continue text onto a subsequent line as long as the continued text starts in the first column of the file.
  
5. The funky colors are so you can see where the labels and text start and stop.
  1. Run the app:
    MultiLineLabels

  2. If you like the multi-line labels, then you’ve come to the wrong place. Our goal here is to reduce the font size of the text so that the label contains only one line of text.

Add a Custom Label Class

  1. Add a custom label class to the LabelWorld project:[sourcecode language=”csharp”] using System; using Xamarin.Forms;

namespace LabelWorld { public class SRLabel : Label {} } [/sourcecode]

  1. Modify the XAML page, LabelWorld.xaml to reference the LabelWorld namespace and use the new SRLabel class in place of Label:[sourcecode language=”xml”] <?xml version=”1.0” encoding=”UTF-8”?>

[/sourcecode]

  1. When you run the app, you will still see the same multi-line labels. But that’s good. It means we added the new custom class correctly.

Add a Custom Renderer

  1. We have done nothing yet to change the font size to fit the width of the label. Now it’s time to fix that. Add a custom renderer to the LabelWorld.iOS project:[sourcecode language=”csharp”] using System; using System.ComponentModel;

using LabelWorld; using LabelWorld.iOS;

using Xamarin.Forms; using Xamarin.Forms.Platform.iOS; using UIKit; using System.Drawing;

[assembly: ExportRenderer (typeof (SRLabel), typeof (SRLabelRenderer))]

namespace LabelWorld.iOS { public class SRLabelRenderer : LabelRenderer { // Override the OnElementChanged method so // we can tweak this renderer post-initial setup protected override void OnElementChanged ( ElementChangedEventArgs

var label = Control as UILabel; if (label != null) { label.AdjustsFontSizeToFitWidth = true; label.Lines = 1; label.BaselineAdjustment = UIBaselineAdjustment.AlignCenters; label.LineBreakMode = UILineBreakMode.Clip; } } } } [/sourcecode]

  1. Run the project and you can see that we’ve now adjusted the font size of each label to fit the text in one line. adjusts-font-size-to-fit-width

We have used text which exaggerates the effect for demonstration purposes. In a real app, you would want to make only small adjustments of the font size. Large adjustments, as we’ve done here, are likely to make your app less usable.

What’s next?

  • Android version
  • In some cases, it would be useful to adjust the height of the label to reflect the font size. When you fetch font metrics in iOS, you can get only the original font size and metrics, not the adjusted size. Please leave a reply if you know how to do that.

Updated: