21

I'm currently trying to add a custom font to my project, but I somehow won't work.

I've already added the .otf file to a font folder, checked that it targets to my project and added Fonts provided by application to Info.plist.

struct ContentView: View {
    var body: some View {
        Text("CLOSEST")
          .foregroundColor(Color("primary"))
          .font(Font.custom("HelveticaNowDisplayBold", size: 60))
    }
}
Tom
  • 3,672
  • 6
  • 20
  • 52
  • 1
    In addition to Andrew's answer, You should also make sure that the fonts are in: Build Phases -> Copy-Bundle Resources. – Brylle May 10 '20 at 14:21

9 Answers9

55

Check the filename

If you have made sure that the Info.plist is using the correct filename:

enter image description here

Note if you are using Xcode 13 you may not have an Info.plist where you expect. This SO answer explains where you can find it.

Check the App Target

Make sure that the font is available in the app's target.

enter image description here

Check the font's actual name

You also need to make sure that you are accessing the font by the correct name.

The font's actual name and the filename may be different.

An easy way to check the font's name is to add the following to your AppDelegate in the didFinishLaunchingWithOptions before the return true. Or if you are using the new SwiftUI lifecycle you can add it to an .onAppear.

for family in UIFont.familyNames.sorted() {
    let names = UIFont.fontNames(forFamilyName: family)
    print("Family: \(family) Font names: \(names)")
}

This will list all the fonts by family and name.

Just remember to remove it once you have finished using it as you don't need to unnecessarily print to the console.

When I do it for my fonts (I have added the same font as you) I find the following in the console in the list of available fonts (see the above screenshot) :

Family: Helvetica Now Display Font names: ["HelveticaNowDisplay-Bold"]

IMPORTANT!!!

Your font may have a different name to mine, and it is important to note that the font name may not be the same as the filename. This is what trips up a lot of people, as they try using the filename when they need to use the font name.

The following test code produces:

struct ContentView: View {
    var body: some View {
        Text("Hello")
            .foregroundColor(.blue)
            .font(Font.custom("HelveticaNowDisplay-Bold", size: 60))
    }
}

enter image description here

For more information about adding custom fonts see Apple's documentation.


Dynamic Type in SwiftUI

If you are using a custom font then you should consider setting it up so that it will scale with dynamic type.

iOS 14

iOS 14 introduces a new modifier that allows you to scale a font relative to a Dynamic Font Type.

Text("Hello")
    .font(.custom("HelveticaNowDisplay-Bold", size: 60, relativeTo: .body))

iOS 13

If you are using iOS 13 that requires a bit more effort to get the same effect.

You first need to create a ViewModifier. This view modifier listens to the size category from the environment (it doesn't actually use it but having it here makes sure the view modifier is updated whenever the size category is updated).

struct ScaledFont: ViewModifier {
    @Environment(\.sizeCategory) var sizeCategory
    var name: String
    var size: CGFloat

    func body(content: Content) -> some View {
       let scaledSize = UIFontMetrics.default.scaledValue(for: size)
        return content.font(.custom(name, size: scaledSize))
    }
}

extension View {
    func scaledFont(name: String, size: CGFloat) -> some View {
        return self.modifier(ScaledFont(name: name, size: size))
    }
}

It is then used in the following way:

Text("Hello")
    .scaledFont(name: "HelveticaNowDisplay-Bold", size: 60)

For a really good write up check out this post on Hacking With Swift.

Andrew
  • 26,706
  • 9
  • 85
  • 101
7

For those people who no longer have a app/scene delegate to put this in. In your <Your_App_Name>App.swift file

init() {
        for family in UIFont.familyNames.sorted() {
            let names = UIFont.fontNames(forFamilyName: family)
            print("Family: \(family) Font names: \(names)")
        }
    }

Will work

Nick
  • 1,315
  • 9
  • 16
4

You need to include the extension of the font (for example .ttf) in the info.plist . I saw a couple of tutorials on youtube, which do not included it, but for me, it does not work without it.

Vikas Saini
  • 483
  • 4
  • 16
Tun Kapgen
  • 81
  • 3
3

Sometimes font file name and the font actual name are different.

In my case my file name was SCRIPTIN.ttf but the actual font name was Scriptina.

I found this by running the following function in App.swift file.

  init() {
            for family in UIFont.familyNames.sorted() {
                let names = UIFont.fontNames(forFamilyName: family)
                print("Family: \(family) Font names: \(names)")
            }
        }

Just put this file after this function in App.swift file and run the app. You will get a list of all loaded files and their names including the newly added font.

var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }

Thank you.

Krishna Karki
  • 749
  • 12
  • 31
2

I had the exact same problem. The following steps fixed it for me. I'm currently using Xcode 11.4.1

  1. Create a storyboard, add a label and select your font in the inspector as font for the label.
  2. Build your App in the Simulator
  3. Check the installed fonts with:

    for family in UIFont.familyNames.sorted() {
        let names = UIFont.fontNames(forFamilyName: family)
        print("Family: \(family) Font names: \(names)")
    }
    
  4. If it's appearing you can use it also programmatically

Here is also a list of Common mistakes with adding custom fonts

Jonas Deichelmann
  • 3,513
  • 1
  • 30
  • 45
2

I had the same issue,

it worked for me when I omitted the "-Regular", but in the info.plist I wrote it with it.

ortalPozniak
  • 131
  • 1
  • 3
  • 2
    Hello! Typically, people are looking for a little more elaboration with answers. I think it is totally possible that you're right, and the font is imbedded incorrectly. However, if you look at other answers to this question, they contain way more information. It's worth it to take a little more time to really get into the details. – Mattie Oct 30 '20 at 14:59
  • 1
    Hello, you're probably right, but the other contributors have already answered and covered all the other options, so I added the only thing that helped me because I already checked the other options that were written there without success – ortalPozniak Nov 02 '20 at 19:19
1

Jonas Deichelmann's answer (to list the fonts available to app) was very helpful to fine tune the Info.plist entries.

Contrary to Apple's example at https://developer.apple.com/documentation/swiftui/applying-custom-fonts-to-text that shows the Fonts provided by application entries to include a relative path to the font files including a subdirectory, I had to provide exclusively the font file name (e.g. Mulish-Regular.ttf with the file extension but without the subdirectory into which the file is stored)

Xcode 14.2

Fred Klein
  • 448
  • 6
  • 13
1

For me fix was to include original font name from "Get Info", NOT the file name.

.font(.custom("FONTSPRING DEMO - Pero Regular", size: 24, relativeTo: .title))

enter image description here

Alex
  • 1,349
  • 11
  • 11
  • That helped me... For SpaceGrotesk.ttf I tried to do "SpaceGrotesk"... than I looked up for a name under Get Info and added space and font started working with "Space Grotesk"... thanks! – Drwalcore Jul 26 '23 at 00:07
0

Xcode 13 Press on target, then info, type Fonts provided by the application and add item font name as like image

enter image description here

Md Tariqul Islam
  • 2,736
  • 1
  • 20
  • 35