7

I am creating a framework for iOS apps. It will contain some Label, Button, Lists, ... all as SwiftUI views, but in a special design. In the framework I've added a SwiftUI view called "ContentView" it has just the purpose of (visually) testing the UI-Elements in the canvas, later the ContentView will be deleted. I wanted to a add a custom font for the label design, I know how to do this:

  1. add the *.ttf file to the project
  2. adapt the info.plist "Fonts provided by app"
  3. made sure, it is listed in "Build phases" (copy bundle resources)
  4. use it with ".font(.custom("My-Font-Name", size: 34))"

But the custom font (that I already tried successfully in an other project, iOS application) is not shown in my ContentView. There is no compile error or any warning, the framework can be built and the ContentView is nicely rendered in the canvas. Only with the wrong font.

I tried restart Xcode, remove and add several times the font, but it didn't work. So here my questions:

  1. Is it possible to use a custom font within a custom framework ?
  2. As the custom font (*.ttf) is kind of an asset, has it to be treated different as part of a framework?
  3. If so, is there anything else to do (besides step 1 to 4 above mentioned) ?

Thanks for helping.

2 Answers 2

11

Tricky little problem, but here's what worked for me:

In the custom framework, I created a FontLoader class:

public class FontLoader {
    static public func loadFont() {
        if let fontUrl = Bundle(for: FontLoader.self).url(forResource: "Opus", withExtension: "otf"),
           let dataProvider = CGDataProvider(url: fontUrl as CFURL),
           let newFont = CGFont(dataProvider) {
            var error: Unmanaged<CFError>?
            if !CTFontManagerRegisterGraphicsFont(newFont, &error)
                {
                    print("Error loading Font!")
            } else {
                print("Loaded font")
            }
        } else {
            assertionFailure("Error loading font")
        }
    }
}

Then, in my AppDelegate's didFinishLaunchingWithOptions, I made sure to import my framework and load the font:

import FontTestFramework
//...
FontLoader.loadFont()

Later, in my view, I used the font successfully with:

Text("Test")
  .font(.custom("Opus", size: 30))

I tested to make sure that it wasn't just loading the version installed on my Mac (since I was using the simulator) but commenting out the FontLoader.loadFont() call, and sure enough, it defaulted back to San Francisco

I tried this with an otf file, but I don't think there's any reason ttf should behave differently. Obviously, the otf file had to be part of the framework's target.

Sign up to request clarification or add additional context in comments.

3 Comments

Wow, man, thanks for your answer. I wonder how much time have you spent, to figure out that solution. Never I've heard of something like 'CTFontManagerRegisterGraphicsFont'. Guess, I will try this the next days.
I happened to run into a scenario recently where my custom font wasn't getting loaded inside a Catalyst application, so I had a running head start having figured out how to deal with that situation. Then it was just a matter of applying it to a framework and making sure it worked there.
This code is outdated, look here stackoverflow.com/questions/30507905/… and search for another Register method ( CTFontManagerRegisterFontsForURL ). Found in the GraphicFont method documentation: "Fonts that are backed by files should be registered using CTFontManagerRegisterFontsForURL(::_:)."
5

I had a similar issue sharing a font with a widget extension - the framework I was using was already built using code similar to the accepted answer (CTFontManagerRegisterGraphicsFont), and it worked just fine in apps themselves, but when I tried to use the framework and the fonts in my widget, it failed to render any of my view code.

What eventually solved it for me was the change suggested in the comment by @itMaxence and in this Apple thread - using CTFontManagerRegisterFontsForURL instead allowed it to work both in the app and in the widget extension.

Just wanted to highlight that comment in case anyone like me stumbles across this thread in the future.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.