I've added custom fonts to my SwiftUI app, following Apple's documentation Applying custom fonts to text. I've added the fonts to my Info.plist
file in the UIAppFonts
key, and they work in my iOS app.
But when using SwiftUI previews, they don't work. Calls to Font.custom("MyFont", size: 17)
just return the system font. Why? How do I fix this?
I've added custom fonts to my SwiftUI app, following Apple's documentation Applying custom fonts to text. I've added the fonts to my Info.plist
file in the UIAppFonts
key, and they work in my iOS app.
But when using SwiftUI previews, they don't work. Calls to Font.custom("MyFont", size: 17)
just return the system font. Why? How do I fix this?
1 Answer
Reset to default 1You'll have to register the fonts manually yourself using CTFontManagerCreateFontDescriptorsFromData
or CTFontManagerRegisterFontsForURL
. Here's example code:
extension View {
public func registerFonts() -> some View {
let fonts = ["montserrat_regular.ttf", "montserrat_bold.ttf", "montserrat_semibold.ttf",
"opensans_regular.ttf", "opensans_semibold.ttf"]
for font in fonts {
guard let url = Bundle.module.url(forResource: font, withExtension: nil) else {
print("Couldn't find font: \(font)")
continue
}
CTFontManagerRegisterFontsForURL(url as CFURL, .process, nil)
}
return self
}
}
Then, in your Preview macro, you have to do this:
#Preview {
MyView()
.registerFonts()
}
This is happening because Xcode Previews don't use the same Info.plist
file as the rest of your app. If you log Bundle.main.infoDictonary
, you'll see that it contains your UIAppFonts
key as expected when running your app, but the key is missing when running in an Xcode Preview.
So, you have to duplicate the UIAppFonts
font list here in the registerFonts()
function, and register the fonts yourself.
Jeremy Gale documents how to do it when your fonts are stored in a separate module, e.g. in a .designSystem
module, you'd use Bundle.designSystem.url
instead of Bundle.module.url
.