xamarin ios monospaced Numbers using UIFontFeature

2019-07-28 05:03发布

问题:

I thought it was now possible in IOS apps to force your numbers to be monospaced when using a custom font. I've found examples and used some code that compiles but my number spacing is still proportional. Has anyone got this working and if so what am I doing wrong?!

Here is my code:

UIFont bigNumberFont = UIFont.FromName("Dosis-Light", 60f);

var originalDescriptor = bigNumberFont.FontDescriptor;
var attributes = new UIFontAttributes(new UIFontFeature(CTFontFeatureNumberSpacing.Selector.MonospacedNumbers),
            new UIFontFeature((CTFontFeatureCharacterAlternatives.Selector)0));

var newDesc = originalDescriptor.CreateWithAttributes(attributes);

UIFont bigNumberMono = UIFont.FromDescriptor(newDesc, 60f);

lbCurrentPaceMinute.Font = bigNumberMono;

My custom font renders fine but I cant get any control over number spacing as of yet. Any suggestions greatly appreciated!

回答1:

First, your code is not making font monospaced.

You are tweaking font to render digits in monospace mode. So all your digits will have same width.

Below is an example with 4 labels, 1 is Docis Light, 2nd is Docis Light with your tweak, 3rd is system font of same size, 4th is system font with your tweak:

As you see, Docis Light is already supporting monospace digits feature out of the box with no tweak.

If you need to use monospaced font, you have to use custom monospaced font (designed to be monospaced) or you can use built-in iOS monospaced fonts such as Courier or Menlo (See all available iOS fonts at http://iosfonts.com/)

This is how they look like with same scenario:

With or without tweaking, they are already monospaced and their digits are monospaced as well.

Finally, if you need to have monospaced digits font (what your code does) you don't need to tweak character alternative. So the code would be:

public static class UIFontExtensions
{
    public static UIFont MonospacedDigitFont(this UIFont font)
    {
        var originalDescriptor = font.FontDescriptor;
        var monospacedNumbersFeature = new UIFontFeature(CTFontFeatureNumberSpacing.Selector.MonospacedNumbers);
        var attributes = new UIFontAttributes(monospacedNumbersFeature);
        var newDescriptor = originalDescriptor.CreateWithAttributes(attributes);
        return UIFont.FromDescriptor(newDescriptor, font.PointSize);
    }
}

Hope this helps! I found it interesting diving into details how you can and cannot tweak fonts in iOS.