Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
C# — Measure string size in Xamarin.Forms for iOS and Android platforms
//
// TextMeter.cs
// Created by Alexey Kinev on 11 Feb 2015.
//
// Licensed under The MIT License (MIT)
// http://opensource.org/licenses/MIT
//
// Copyright (c) 2015 Alexey Kinev <alexey.rudy@gmail.com>
//
// Usage example:
//
// var label = new Label {
// Text = "La-la-la-laaaaaaaaaaaaaaaaa! And even more La-la-la-laaaaa!",
// FontSize = 16.0,
// };
// label.FontFamily = Device.OnPlatform (
// iOS: "HelveticaNeue"
// Android: "Roboto"
// );
// var labelHeight = TextMeter.MeasureTextSize(
// label.Text, 200, label.FontSize, label.FontFamily).Height;
//
using System;
using Xamarin.Forms;
#if __IOS__
using System.Drawing;
using Foundation;
using UIKit;
namespace ZeroFiveBit.Forms.Utils
{
public static class TextMeterImplementation
{
public static Xamarin.Forms.Size MeasureTextSize(string text, double width,
double fontSize, string fontName = null)
{
var nsText = new NSString(text);
var boundSize = new SizeF((float)width, float.MaxValue);
var options = NSStringDrawingOptions.UsesFontLeading |
NSStringDrawingOptions.UsesLineFragmentOrigin;
if (fontName == null)
{
fontName = "HelveticaNeue";
}
var attributes = new UIStringAttributes {
Font = UIFont.FromName(fontName, (float)fontSize)
};
var sizeF = nsText.GetBoundingRect(boundSize, options, attributes, null).Size;
return new Xamarin.Forms.Size((double)sizeF.Width, (double)sizeF.Height);
}
}
}
#endif
#if __ANDROID__
using Android.Widget;
using Android.Util;
using Android.Views;
using Android.Graphics;
namespace ZeroFiveBit.Forms.Utils
{
public static class TextMeterImplementation
{
private static Typeface textTypeface;
public static Xamarin.Forms.Size MeasureTextSize(string text, double width,
double fontSize, string fontName = null)
{
var textView = new TextView(global::Android.App.Application.Context);
textView.Typeface = GetTypeface(fontName);
textView.SetText(text, TextView.BufferType.Normal);
textView.SetTextSize(ComplexUnitType.Px, (float)fontSize);
int widthMeasureSpec = Android.Views.View.MeasureSpec.MakeMeasureSpec(
(int)width, MeasureSpecMode.AtMost);
int heightMeasureSpec = Android.Views.View.MeasureSpec.MakeMeasureSpec(
0, MeasureSpecMode.Unspecified);
textView.Measure(widthMeasureSpec, heightMeasureSpec);
return new Xamarin.Forms.Size((double)textView.MeasuredWidth,
(double)textView.MeasuredHeight);
}
private static Typeface GetTypeface(string fontName)
{
if (fontName == null)
{
return Typeface.Default;
}
if (textTypeface == null)
{
textTypeface = Typeface.Create(fontName, TypefaceStyle.Normal);
}
return textTypeface;
}
}
}
#endif
namespace ZeroFiveBit.Forms.Utils
{
public static class TextMeter
{
public static Xamarin.Forms.Size MeasureTextSize(string text, double width,
double fontSize, string fontName = null)
{
return TextMeterImplementation.MeasureTextSize(text, width, fontSize, fontName);
}
}
}
@wizche

This comment has been minimized.

Copy link

wizche commented Feb 12, 2015

if WP? :)

@rudyryk

This comment has been minimized.

Copy link
Owner Author

rudyryk commented Feb 14, 2015

@wizche That would be great, but I don't have Windows machine and WP device :)

@jmganesh

This comment has been minimized.

Copy link

jmganesh commented Mar 16, 2015

How do we use this? Could you please post your sample code here?

@rudyryk

This comment has been minimized.

Copy link
Owner Author

rudyryk commented May 19, 2015

@jmganesh I've updated the gist and added an example of usage.

@JamesKelley

This comment has been minimized.

Copy link

JamesKelley commented Aug 25, 2015

I don't understand what the "width" parameter is. Can you please explain what value I am suppose to pass in.

@rudyryk

This comment has been minimized.

Copy link
Owner Author

rudyryk commented Jan 19, 2016

@JamesKelley this is maximum text width in pixels to fit in. It is common to have limited width and variable height, i.e. in news feed with text posts etc. For example, you may pass screen width minus left and right padding, that actually depends on your layout.

@Aspro1

This comment has been minimized.

Copy link

Aspro1 commented Feb 16, 2016

How should I use the code? I put it into the portable project of my Xamarin.Forms solution and it does not compile (“The name 'TextMeterImplementation' does not exist in the current context”), both “#if…#endif” blocks are greyed out and the compiler ignores them.

I had to use DependencyService to make it work.

@Aspro1

This comment has been minimized.

Copy link

Aspro1 commented Feb 16, 2016

I see on Android that if I make a label with the text “iiiiiiiiiiiiiiiiiiii” and I compare the width of the label with the measured width of its text, for some font sizes (15, 16, 17, 23, 24, 25, 31, 32, 33) the difference is less than 1, but for others (18 to 22) the difference is about 6.

@rudyryk

This comment has been minimized.

Copy link
Owner Author

rudyryk commented Sep 29, 2016

Text meter is now part of the misc utils package:
https://github.com/TheUniforms/Uniforms-Misc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.