'In iOS, Is it possible to add a font to the app during runtime?

In my app I want to let the user download and use fonts, but I don't know how to do this dynamically. I know we have to specify the fonts we want to use in the app's Info.plist file, but we can't add anything to that plist file programmatically. There is zynga's library but it is a subclass of UILabel.

Please help



Solution 1:[1]

Yes, it is possible:

/**
 Downloads a `.ttf` file from an URL and creates an UIFont.
 
 - Parameter url: The URL of the `.ttf` file.
 
 - Precondition: The URL Session must be previously configured at ease.
 */
fileprivate func setFont(url: URL) {
    // Download the font file in .ttf format.
    dataTask = urlSession?.dataTask(with: url,
                                    completionHandler: { [weak self] (data, response, error) in
        guard error == nil,
            let data = data,
            (response as? HTTPURLResponse)?.statusCode == 200,
            // Create a Font Descriptor from the raw data.
            let ctFontDescriptor = CTFontManagerCreateFontDescriptorFromData(data as CFData) else {
                // Error during the download of the .ttf file.
                self?.error()
                return
        }
        // Create CTFont from the Font Descriptor and convert it to UIFont.
        let font: UIFont = CTFontCreateWithFontDescriptor(ctFontDescriptor, 0.0, nil) as UIFont
        // Do whatever you want with the UIFont :)
        self?.success(font: font)
    })
    dataTask?.resume()
}

With this code, you can download a .ttf file from the Internet (you could get the file from any other source) containing a font and use it as UIFont.

Solution 2:[2]

It's actually possible to download and register a font during runtime, you need download the font to a local folder and then you can use CTFontManagerRegisterFontsForURL or CTFontManagerRegisterGraphicsFont to register it.

I found that CTFontManagerRegisterFontsForURL seems to load TTF with mutiple styles while using CGDataProvider with CTFontManagerRegisterGraphicsFont only loads one.

Remember that URL need to be an internal URL, not an http one.

    var unmanagedError: Unmanaged<CFError>?
    if CTFontManagerRegisterFontsForURL(url as CFURL, .process, &unmanagedErrorT) == true {
         // SUCCESS CODE
    } else {
         // ERROR CODE
         unmanagedError?.release()
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Pau Ballada