-
-
Save rudyryk/7b9633e847e727d12de7 to your computer and use it in GitHub Desktop.
// | |
// 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); | |
} | |
} | |
} |
I don't understand what the "width" parameter is. Can you please explain what value I am suppose to pass in.
@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.
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.
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.
Text meter is now part of the misc utils package:
https://github.com/TheUniforms/Uniforms-Misc
@jmganesh I've updated the gist and added an example of usage.