Adding custom fonts to iOS app finding their real names
Asked Answered
O

11

40

I have two fonts to add in my app for using.

Here is the font images. Currently the files are named as

name.font       = [UIFont fontWithName:@"Helvetica Neue LT Pro-Medium" size:10];
headline.font   = [UIFont fontWithName:@"Helvetica Neue LT Pro-Light" size:8];

putting same name in the Font Avaliable option in plist file.

I have also tried adding file names like

HelveticaNeueLTPro-Lt
HelveticaNeueLTPro-Md

but nothing seems to work. How can i get the exact name of the fonts.

enter image description here

Oversubtlety answered 13/4, 2013 at 6:23 Comment(5)
Do you really want to add fonts to Xcode? Isn't it rather your iOS app?Joellenjoelly
try this #14377441Lipscomb
@H2CO3 i mean to say my app :)Oversubtlety
@NaCl yes i know all these steps. i am just confused with what names should be placed in the plist key and in in UIFont NamedOversubtlety
Check out this: #361251Glockenspiel
A
85

Use +[UIFont familyNames] to list all of the font family names known to the system. For each family name, you can then use +[UIFont fontNamesForFamilyName:] to list all of the font names known to the system. Try printing those out to see what name the system expects. Example code:

static void dumpAllFonts() {
    for (NSString *familyName in [UIFont familyNames]) {
        for (NSString *fontName in [UIFont fontNamesForFamilyName:familyName]) {
            NSLog(@"%@", fontName);
        }
    }
}

Put that in your app, call it, and see what you get. If you see a name in the output that looks appropriate for your font, use it. Otherwise, perhaps you haven't properly added the font to your app.

In Swift:

func dumpAllFonts() {
    for familyName in UIFont.familyNames {
        for fontName in UIFont.fontNames(forFamilyName: familyName) {
            print(fontName)
        }
    }
}
Affecting answered 13/4, 2013 at 6:49 Comment(2)
i checked, my fonts weren't there. It seems the files weren't added in resources so i added them and now they work properly thanksOversubtlety
If you want to check in Swift: for familyName in UIFont.familyNames() { if let fn = familyName as? String { for font in UIFont.fontNamesForFamilyName(fn) { println("font: \(font)") } } }Ellaelladine
S
53

While it appears that UIFont's fontNamed:size: method is fairly forgiving with the names you provide, the official fontName has always been the font's internal PostScript name. A font's PostScript name cannot contain spaces and usually has them replaced by a hyphen. I don't recall offhand, but I believe they may also be limited to 31 characters.

Determining what name you should use in code is extremely simple. Double click on the font you want to use on your iOS device to open it in Font Book. If the font is not already installed, click the Install button in the sample window that appears. When it's installed, select the font in the Font list. In Font Book's menu, choose Preview > Show Font Info. That will show info about the font like shown in the image below:

enter image description here

As you can see, the PostScript name for Helvetica Neue LT Std 65 Medium is HelveticaNeueLTStd-Md. That's the name you should use in code.

In your Info.plist file, under fonts for the application, you need to use the actual filename of the font itself, whatever that happens to be. In my case, it was HelveticaNeueLTStd-Md.otf.

Snowberry answered 13/4, 2013 at 7:25 Comment(1)
As an interesting expansion upon this, Xcode will show strange behavior if you include a font, but name it incorrectly. For instance, I added the "Sport World-Light" font in my plist, but the actual font file I included in my project was "Sports World-Regular." The app loaded the font correctly, even though I had the wrong name. It gave me a weird start up failure, but continued through it -- see more here: #26248993Latvia
H
51

This is Step for, How to add custom font in Application.

1 - Add .TTF font in your application
2 - Modify the application-info.plist file.
3 - Add the key "Fonts provided by application" to a new row
4 - and add each .TTF file (of font) to each line.

Also read This and This tutorials for improve your knowledge.

FOR MOREINFORMATION :

But after adding font to your application, sometimes might be the font name is not the name of the file name so you need to apply/write real name of your font, so check @NSGod's answer.

Following is code for find all fonts from the system:

for(NSString *fontfamilyname in [UIFont familyNames])
{
    NSLog(@"Family:'%@'",fontfamilyname);
    for(NSString *fontName in [UIFont fontNamesForFamilyName:fontfamilyname])
    {
        NSLog(@"\tfont:'%@'",fontName);
    }
    NSLog(@"~~~~~~~~");
}

Might be above step and suggestion is helpful in your case:

Hexastich answered 13/4, 2013 at 6:48 Comment(5)
Neither of those methods is part of the public API. Using either one will make your app fail its review.Affecting
@"FontName" WITHOUT extensions For example UILabel *label; label.font = [UIFont fontWithName:@"MyriadPro-Light" size:36.0];Fleer
@rob I'm not understanding how what is in this answer is different than your answer and therefore how this would get an app rejected and yours won't. maybe it's just year old posts or something. But I just used your method (check marked) to get the font names and until I did what he said here my fonts were not included in that list.Earthen
You have to add the font to application-info.plist, as this answer advises. However, in this answer's example code, he uses two private methods: fontWithFamilyName:traits:size: and fontWithMarkupDescription:. Since neither of those is part of the public iOS SDK, Apple is likely to reject your app if it uses either of them.Affecting
@robmayoff - Thanks for correct me.. I really don't know about when I wrote this answer. :) You can check my edited answer:) Thanks again :)Hexastich
D
9

Easier way to get the name of the font

  1. Right-click on your .ttf/.otf file and choose "Get Info"
  2. Read the Full Name property and use that as the name of the font

It works both in the info .plist file (adding the extension) and in the code with [UIFont fontWithName:<Full Name> size:17]

Detent answered 13/4, 2013 at 7:21 Comment(4)
this is not always the case. you should choose the postscript name and not the full nameKicker
Sorry this is wrong. The file name is often, but not always the same as the font name. As for full name I checked a pesky font file I have. Full Name = "Source Sans Pro Italic"; filename = "SourceSansPro-Italic.ttf"; font name is "SourceSansPro-It" - notice how they're all different. I just wasted a bunch of time on this. The right way to do it is to add the files, add the file names to the plist, then do a printout of all font names. PS: I tested the full name on my font file too, as expected doesn't work.Mandolin
this should be your first guess. if it doesn't work look at the other options... you can also install the font by opening it up in FontBook on Mac OS X.Chequer
Even if that's not quite correct it saved my day pointing me to the right directionJeuz
H
3

Just NSLog The font you want get:

NSLog(@" %@", [UIFont fontNamesForFamilyName:@"American Typewriter"]);

And you get the array:

(
  "AmericanTypewriter-CondensedLight",
  "AmericanTypewriter-Light",
  "AmericanTypewriter-Bold",
  AmericanTypewriter,
  "AmericanTypewriter-CondensedBold",
  "AmericanTypewriter-Condensed"
)

Use any you need in Code any of font names AmericanTypewriter-Bold as [UIFont fontWithName:@"AmericanTypewriter-Bold" size:12.0]

Also you could get All Applied Fonts grouped by Font Family

for (NSString* family in [UIFont familyNames])
{
    NSLog(@"%@", family);

    for (NSString* name in [UIFont fontNamesForFamilyName: family])
    {
        NSLog(@"  %@", name);
    }
}
Horseshoes answered 16/8, 2013 at 9:22 Comment(0)
P
3

I write some code to print out only font name that you want, not just print out all fonts.

- (NSString *)realNameOfFont:(NSString *)fullFontName {
    NSString *fontName = [[fullFontName componentsSeparatedByString:@"."] firstObject];
    NSString *ext = [fullFontName pathExtension];

    NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:fontName ofType:ext]];
    if (data == nil) {
        NSLog(@"Failed to load font. Data at path %@ is null", fullFontName);
        return nil;
    }
    CFErrorRef errorRef;
    CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)data);
    CGFontRef font = CGFontCreateWithDataProvider(provider);
    NSString *realFontName = (__bridge NSString *)CGFontCopyPostScriptName(font);
    if (!CTFontManagerRegisterGraphicsFont(font, &errorRef)) {
        NSError *error = (__bridge NSError *)errorRef;
        if (error.code != kCTFontManagerErrorAlreadyRegistered) {
            NSLog(@"Failed to load font: %@", error);
        }
    }
    NSLog(@"Real font name: %@", realFontName);
    CFRelease(font);
    CFRelease(provider);
    return realFontName;
}

Example:

 NSArray *fonts = @[@"bg_en_AmaticSC-Bold111.otf", @"bg_en_segoescb_0.ttf", @"bg_en_UTM Cookies_2.ttf", @"bg_en_VSCOProximaExtrabold_0.otf"];
for (NSString *fontFullName in fonts) {
    [self realNameOfFont:fontFullName];
}

Result:

Failed to load font. Data at path bg_en_AmaticSC-Bold111.otf is null
Real font name: SegoeScript-Bold
Real font name: UTM-Cookies
Real font name: ProximaNova-Extrabld
Portly answered 12/8, 2015 at 4:14 Comment(0)
A
3

Nothing wrong with the other answers. In fact iPatel's prerequisites continue to apply.

In Swift 2.2+, the call to show the family names is simply:

  UIFont.familyNames().sort().forEach({ (familyName) in
            debugPrint(UIFont.fontNamesForFamilyName(familyName))
        })

If you have installed the fonts on your system, you could also simply add the fonts to your UI element in the storyboard.

Note

However, I have noticed a bug in some cases where after one add the fonts properly to the project, info.plist, and UI elements in the storyboard, they still do not properly reflect your desired changes. In some cases toggling the settings will help the Storyboard sync it's underlying xml. In other cases you might need to simply update the size of your custom font in code to have the changes take effect. The simplest method in Swift that I have found is:

@IBOutlet weak var startMessage: UILabel!
startMessage.font = UIFont(name: startMessage.font.familyName, size: 31.0)

Which assumes the custom font is already set in the Storyboard and simply updates the size in code. This workaround would ensure that if all other prerequisites are met that you actually see the correct custom typeface. It also removes the need to actually know the underlying font name (although if desired the initial Swift code above will give you the name).

Aweinspiring answered 4/5, 2016 at 1:51 Comment(0)
G
3

Swift version:

static func printAllFontNames() {
    for familyname in UIFont.familyNames() {
        for fname in UIFont.fontNamesForFamilyName(familyname) {
            print(fname)
        }
    }
}
Galliwasp answered 5/1, 2017 at 15:31 Comment(0)
O
1

Swift 3 version:

UIFont.familyNames.sorted().forEach({ (familyName) in
            print(UIFont.fontNames(forFamilyName: familyName))
        })
Oud answered 6/4, 2017 at 17:43 Comment(0)
M
1

Update for swift 3

for familyname in UIFont.familyNames {
            for fname in UIFont.fontNames(forFamilyName: familyname) {
                print(fname)
            }
        }
Micromho answered 8/5, 2017 at 14:33 Comment(0)
D
0

Create a new single view app

Create a group in your app named Fonts, drop in your font files (tick copy files if needed).

In info.plist, add "Fonts provided by application", add each item for each font eg, item 0: AlexBrush-Regular.ttf, item 1: Fipps-Regular.otf

Or edit info.plist directly:

<key>UIAppFonts</key>
<array>
    <string>AlexBrush-Regular.ttf</string>
    <string>Fipps-Regular.otf</string>
</array>

Cut and paste this swift 5 code into ViewController.swift, run in a simulator, add a filter in the console log using your font name

//
//  ViewController.swift
//  FontsApp
//
//  Created by Gary Davies on 28/3/19.
//  Copyright © 2019 Gary Davies. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    var fontFamilyNames: [String] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        fontNames()
    }

    func fontNames() {
        getFontNames()
        sortFontNames()
        printFontName()
    }

    func getFontNames() {
        fontFamilyNames.removeAll()
        for name in UIFont.familyNames {
            fontFamilyNames.append(name)
        }
    }

    func sortFontNames() {
        let sorted = fontFamilyNames.sorted { $0.localizedCaseInsensitiveCompare($1) == ComparisonResult.orderedAscending }
        fontFamilyNames.removeAll()
        for name in sorted {
            fontFamilyNames.append(name)
        }
    }

    func printFontName() {
        for name in fontFamilyNames {
            print(name, "=>", UIFont.fontNames(forFamilyName: name))
        }
    }
}

(Sorry this is not a duplicate, I added the wrong answer to the wrong question)

Drypoint answered 28/3, 2019 at 4:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.