iOS Monospaced Custom Font
Asked Answered
A

3

3

I have a custom font included in my Xcode 7, iOS 9 targeted project. I want to make the font monospaced. I tried this, and didn't work:

let originalFont = UIFont(name: "My Custom Font", size: 18)
let originalFontDescriptor = originalFont!.fontDescriptor()

let fontDescriptorFeatureSettings = [
    [
        UIFontFeatureTypeIdentifierKey: kNumberSpacingType,
        UIFontFeatureSelectorIdentifierKey: kMonospacedNumbersSelector
    ]
]

let fontDescriptorAttributes = [UIFontDescriptorFeatureSettingsAttribute: fontDescriptorFeatureSettings]
let fontDescriptor = originalFontDescriptor.fontDescriptorByAddingAttributes(fontDescriptorAttributes)
let font = UIFont(descriptor: fontDescriptor, size: 0)

topLabel.font = font

With or without above code, the label displayed in proper custom font. It's just above code doesn't do anything.

Allocate answered 2/1, 2016 at 22:34 Comment(3)
the code looks like it will work. Is it possible that the location of the font setting is wrong? Where are you doing this?Meingolda
That's where I was going. How do I get the location of the font setting?Allocate
I don't think a non-monospaced font can simply be used as a monospaced font. The font is either monospaced or it isn't.Paske
T
5

My following answer is only making numbers (not the whole font) of an existing font monospaced (if the font supports it)

At least I was searching for making numbers monospaced when finding this Thread. So I hope it will help although it answers another question.

This works just fine, tested on Swift 5 and iOS14+13:

(As long as "your font is supporting the monospaced digits feature".)

extension UIFont {

    var monospacedDigitFont: UIFont {
        let oldFontDescriptor = fontDescriptor
        let newFontDescriptor = oldFontDescriptor.monospacedDigitFontDescriptor
        return UIFont(descriptor: newFontDescriptor, size: 0)
    }

}

private extension UIFontDescriptor {

    var monospacedDigitFontDescriptor: UIFontDescriptor {
        let fontDescriptorFeatureSettings = [[UIFontDescriptor.FeatureKey.featureIdentifier: kNumberSpacingType, UIFontDescriptor.FeatureKey.typeIdentifier: kMonospacedNumbersSelector]]
        let fontDescriptorAttributes = [UIFontDescriptor.AttributeName.featureSettings: fontDescriptorFeatureSettings]
        let fontDescriptor = self.addingAttributes(fontDescriptorAttributes)
        return fontDescriptor
    }
}

Then you can use it on any label like this:

/// Label with monospacing activated
myLabel.font = myLabel.font.monospacedDigitFont

/// Label with monospacing not activated (default is proportional spacing)
myLabel.font = myLabel.font

(source: https://blog.usejournal.com/proportional-vs-monospaced-numbers-when-to-use-which-one-in-order-to-avoid-wiggling-labels-e31b1c83e4d0)

Thaxton answered 1/10, 2020 at 13:28 Comment(0)
S
1

The code you are using is not making font monospaced.

It's tweaking font to render digits in monospace mode. So all with this font digits will have same width.

Below is an example with 4 labels, 1 is using custom font Docis Light, 2nd is Docis Light with monospaced digits on, 3rd is system font of same size, 4th is system font with monospaced digits on:

monospaced digits font tweak in ios

As you see, this custom font already supports monospace digits feature out of the box with no tweak required.

If you need to use monospaced (not just digits) 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:

courier and menlo monospaced iOS fonts

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

I answered similar question here, probably, I should just link the answer instead of images but it so much more visual.

Sherr answered 14/10, 2016 at 5:4 Comment(0)
T
0

Don't forget to import the header file. Hope it will work. This solution is in Objective-C

#import <CoreTextArcView.h>

UIFont *const existingFont = [UIFont preferredFontForTextStyle:   UIFontTextStyleBody];
UIFontDescriptor *const existingDescriptor = [existingFont fontDescriptor];

NSDictionary *const fontAttributes = @{

UIFontFeatureTypeIdentifierKey 

UIFontDescriptorFeatureSettingsAttribute: @[
 @{
   UIFontFeatureTypeIdentifierKey: @(kNumberSpacingType),
   UIFontFeatureSelectorIdentifierKey: @(kMonospacedNumbersSelector)
  }]
};

UIFontDescriptor *const monospacedDescriptor = [existingDescriptor  fontDescriptorByAddingAttributes: fontAttributes];
UIFont *const proportionalFont = [UIFont fontWithDescriptor: monospacedDescriptor size: [existingFont pointSize]];
Torin answered 11/6, 2018 at 7:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.