60

I'm currently working on an app that uses the "ChalkboardSE-Regular" font and my deployment target is 4.0+. This font was not available in 4.1 but it is supported in 4.3. What would be the best way to go about checking if the font exists and if it does not, use another supported font on the <4.1 versions of iOS. [UIFont familyName] returns a list of these fonts "Chalkboard SE"

Thanks in advance!

T

tg2007
  • 841
  • 1
  • 9
  • 18

15 Answers15

114

[UIFont familyName] is supported back to iPhone OS 2.0 (before 2.0, third-party apps were not allowed on iPhone or iPod touch) , so I would use that to check to see if a font family exists on the current device, and if it doesn't exist, use a suitable fall-back font for that version of iOS. Here's John Gruber's list of iPhone fonts from the original iPhone in 2007 (contrasted with the fonts in Mac OS X of the day). I haven't checked them all, but the iOS fonts I did check are still in iOS 5:

Here's an example of using [UIFont familyName]:

NSLog (@"Font families: %@", [UIFont familyNames]);

This will produce a list like this:

Font families: ( Thonburi, "Snell Roundhand", "Academy Engraved LET", ... et cetera.

Once you know the family name, you can use the UIFont class method fontNamesForFamilyName to get an NSArray of the names of all the fonts in the family. For example:

NSLog (@"Courier New family fonts: %@", [UIFont fontNamesForFamilyName:@"Courier New"]);

That will produce a list like this:

Courier New family fonts: ( CourierNewPSMT, "CourierNewPS-BoldMT", "CourierNewPS-BoldItalicMT", "CourierNewPS-ItalicMT" )

The following example code prints a list of each font in every family on the current device:

NSArray *fontFamilies = [UIFont familyNames];

for (int i = 0; i < [fontFamilies count]; i++)
{
    NSString *fontFamily = [fontFamilies objectAtIndex:i];
    NSArray *fontNames = [UIFont fontNamesForFamilyName:[fontFamilies objectAtIndex:i]];
    NSLog (@"%@: %@", fontFamily, fontNames);
}

For more information, check out the iOS Developer Reference document for the UIFont class methods familyNames and fontNamesForFamilyName:.

Steve HHH
  • 12,947
  • 6
  • 68
  • 71
  • 1
    I also wrote an app to dump them all with sample text. Might just want to start with this https://github.com/palmerc/iOS5Fonts – Cameron Lowell Palmer Mar 07 '13 at 14:43
  • this would be the same in swift: for family:String in (UIFont.familyNames() as String[]) { println(family) for name:String in (UIFont.fontNamesForFamilyName(family) as String[]) { println("\t \(name)") } } – magegu Jun 30 '14 at 10:04
59

If you use Swift you can print all fonts (see below). You can also check if the font exists.

for family in UIFont.familyNames {
    print("\(family)")

    for name in UIFont.fontNames(forFamilyName: family) {
        print("   \(name)")
    }
}
Akbar Khan
  • 2,215
  • 19
  • 27
Alessandro Pirovano
  • 2,509
  • 28
  • 21
16

Swift 5.x

Forget those for-loops, this is the easiest way to see fonts supported by iOS.

Just run any of the following in a playground.


Family Names Only

Input

dump(UIFont.familyNames)

Output

▿ 75 elements
  - "Copperplate"
  - "Heiti SC"
  - "Kohinoor Telugu"
  ...

Font Names Only

Input

dump(UIFont.familyNames.compactMap { UIFont.fontNames(forFamilyName: $0) })    

Output

▿ 248 elements
  - "Copperplate-Light"
  - "Copperplate"
  - "Copperplate-Bold"
  ...

Font Names for Specified Family Name

Input

dump(UIFont.fontNames(forFamilyName: "Helvetica Neue"))

Output

▿ 14 elements
  - "HelveticaNeue-Italic"
  - "HelveticaNeue-Bold"
  - "HelveticaNeue-UltraLight"
  - "HelveticaNeue-CondensedBlack"
  ...
Beau Nouvelle
  • 6,962
  • 3
  • 39
  • 54
  • 1
    Very helpful!! Thanks! – m_katsifarakis Aug 28 '17 at 18:06
  • 1
    How the heck did I not know about dump? Nice – Shayne Mar 20 '19 at 04:13
  • 1
    For the Font Names Only example above, the compactMap method generates a two dimensional array of strings grouped by the font names. If you need all of the font names to be in a single array of strings, use flatMap instead of compactMap. – BP. Jul 02 '21 at 19:34
14

This font was not available in 4.1 but it is supported in 4.3. What would be the best way to go about checking if the font exists

Simply ask for the font in the usual way using UIFont* f = [UIFont fontWithName:... size:...];. If the font isn't available, the result (f) will be nil.

(One way to guarantee the availability of a font is to include it in the app bundle...)

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Can you please elaborate on that? ("include it in the app bundle") How would you do it, where (from) can you copy it, won't it violate (a dozen or so) laws/copyrights/etc? I am asking, because in the iOS6 the MarkerFelt font has a "bug". The Greek letter s (final sigma) is shown like the lowercase Zeta... Can I include the iOS5 MarkerFelt on my App? And how would I go about it? – Gik Oct 22 '12 at 10:53
  • A font is like any other resource in your project. If it's included in the Copy Bundle Resources build phase, it's, uh, copied into your bundle. See my book: http://www.apeth.com/iOSBook/ch06.html#_the_target. Note that you'll need to set the UIAppFonts key in your Info.plist, to alert the runtime that there's a font in your bundle that needs fetching. – matt Oct 22 '12 at 15:40
4

For iOS9 / Swift 2.0, none of above won't work as the syntax changed a little. I also personally prefer to use extension (I choose to create one for UIFont, as it fits the best and modified @API answer as this was the best one):

extension UIFont {

    static func availableFonts() {

        // Get all fonts families
        for family in UIFont.familyNames() {
            NSLog("\(family)")

            // Show all fonts for any given family
            for name in UIFont.fontNamesForFamilyName(family) {
                NSLog("   \(name)")
            }
        }
    }
} 

Now you can just call:

UIFont.availableFonts()

And it will tell you all the fonts in the form of

: Bangla Sangam MN
:    BanglaSangamMN-Bold
:    BanglaSangamMN
: Zapfino
:    Zapfino

Hope it helps!

Jiri Trecak
  • 5,092
  • 26
  • 37
2

This is what i did on objective c to find out if font is available or not

NSFont *font = [NSFont fontWithName:@"thefont" size:25.0];
if (font==nil) {
    // thefont is available
} else {
    // thefont is not available
}
2

Swift version:

UIFont.familyNames().sort( { $0 < $1 } ).forEach({ print("\($0)"); UIFont.fontNamesForFamilyName("\($0)").sort( { $0 < $1 } ).forEach({ print("     \($0)") }) })
eMdOS
  • 1,693
  • 18
  • 23
2

Well, rather than writing a single line of code, you can just open http://iosfonts.com and check availability based on your iOS version support. You can also know how would it look like.

http://iosfonts.com Preview Feature

Sauvik Dolui
  • 5,520
  • 3
  • 34
  • 44
1

Here is a conversion of Steves answer to Swift code (for quick copy and paste purpose):

    var fontFamilies = UIFont.familyNames()

    for (var i:Int = 0; i < fontFamilies.count; i++) {
        var fontFamily: NSString = fontFamilies[i] as NSString
        var fontNames: NSArray = UIFont.fontNamesForFamilyName(fontFamilies[i] as String) as NSArray

        NSLog ("%@: %@", fontFamily, fontNames)
    }
Pontus
  • 776
  • 7
  • 12
1

Try to init with that font name, and if it's nil do something else. Swift code:

if let font = UIFont(name: name, size: size) { // ok } else { // not ok }

superarts.org
  • 7,009
  • 1
  • 58
  • 44
1

I figured that using swiftui preview, you can make a app that shows what each font looks like using the preview simulator.

struct TitleViewModifier_Previews:
    PreviewProvider {
    
    static var previews: some View {

        List{
            ForEach(UIFont.familyNames.sorted(),id: \.self){ family in
                ForEach(UIFont.fontNames(forFamilyName: family), id: \.self){ eachFont in
                    Text(eachFont)
                        .font(.custom(eachFont, size: 22))
                }
            }
        }
    }
}

Here is what my preview looks like Press the play button to make the list interactive and scrollable

enter image description here

Nic Wanavit
  • 2,363
  • 5
  • 19
  • 31
0

For objective-c

for (NSString *family in UIFont.familyNames) {
    NSLog(@"family %@",family);
    for (NSString *name in [UIFont fontNamesForFamilyName:family]) {
        NSLog(@"      name = %@",name);
    }
}
Hardik Thakkar
  • 15,269
  • 2
  • 94
  • 81
0

Swift 4.x

UIFont.familyNames().sort( { $0 < $1 } ).forEach({ print("\($0)"); UIFont.fontNamesForFamilyName("\($0)").sort( { $0 < $1 } ).forEach({ print("     \($0)") }) })

Swift 5.x

UIFont.familyNames.sorted( by: { $0 < $1 } ).forEach({ print("\($0)"); UIFont.fontNames(forFamilyName: "\($0)").sorted(by: { $0 < $1 } ).forEach({ print("     \($0)") }) })
Mercurial
  • 2,095
  • 4
  • 19
  • 33
0

print("Font families: %@", UIFont.familyNames)

Wasim
  • 921
  • 12
  • 14
0

To check if UIFont is registered:

let fontName = "Helvetica"
UIFont.familyNames.flatMap(UIFont.fontNames).contains(fontName)
Tal Sahar
  • 784
  • 1
  • 7
  • 10