iOS Monospaced Custom Font

前端 未结 3 1888
生来不讨喜
生来不讨喜 2021-01-24 09:08

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 = UIF         


        
相关标签:
3条回答
  • 2021-01-24 09:21

    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:

    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:

    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.

    0 讨论(0)
  • 2021-01-24 09:32

    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]];
    
    0 讨论(0)
  • 2021-01-24 09:34

    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.monospacedDigitFontDescriptor
    
    /// 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)

    0 讨论(0)
提交回复
热议问题