Xcode: Using custom fonts inside Dynamic framework
I'm here a bit late, but I took PetahChristian's solution and created a Swift version in the form of an extension. This is working for me. I've found that when you try to get a font using a font name and a size using the regular way that it always looks in the main bundle for the font file, and there's no method that takes a bundle identifier as a parameter. It would be nice if Apple would make one.
Swift:
public extension UIFont {
public static func jbs_registerFont(withFilenameString filenameString: String, bundle: Bundle) {
guard let pathForResourceString = bundle.path(forResource: filenameString, ofType: nil) else {
print("UIFont+: Failed to register font - path for resource not found.")
return
}
guard let fontData = NSData(contentsOfFile: pathForResourceString) else {
print("UIFont+: Failed to register font - font data could not be loaded.")
return
}
guard let dataProvider = CGDataProvider(data: fontData) else {
print("UIFont+: Failed to register font - data provider could not be loaded.")
return
}
guard let font = CGFont(dataProvider) else {
print("UIFont+: Failed to register font - font could not be loaded.")
return
}
var errorRef: Unmanaged? = nil
if (CTFontManagerRegisterGraphicsFont(font, &errorRef) == false) {
print("UIFont+: Failed to register font - register graphics font failed - this font may have already been registered in the main bundle.")
}
}
}
Usage Example:
UIFont.jbs_registerFont(
withFilenameString: "Boogaloo-Regular.ttf",
bundle: Bundle(identifier: "com.JBS.JBSFramework")!
)
Custom font in framework for SwiftUI
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?
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.
Can I embed a custom font in a bundle and access it from an ios framework?
This is a new method that lets you load fonts dynamically without putting them in your Info.plist: http://www.marco.org/2012/12/21/ios-dynamic-font-loading
Custom font inside Cocoa Touch Static Library
You can provide an example plist or even write a utility that performs this setting by updating a given property list, but the users of the library will need to do something themselves, either updating the plist manually or by using your utility. You can't avoid this.
Related Topics
Making Button Span Across VStack
Set Insets to the Collectionview Programmatically in Swift
Type of Optionals Cannot Be Inferred Correctly in Swift 2.2
Enum's Rawvalue Property Not Recognized
Swift iOS 9: Section Header Change Position After Reload Data
Swift Error: 'Sequence' Requires the Types 'T' and 'Arrayslice<T>' Be Equivalent
Difficulties to Assign Default Value to a Parameter of a Function
Uisegment Value Changing When Tableview Get Scrolled
Adding Elements on Many-To-Many Relation
Attributed Text, Replace a Specific Font by Another Using Swift
In Swift, How to Wait Until a Server Response Is Received Before I Proceed
How to Specify the Type Information of an Array That Would Hold Swiftui Custom Views
Swift Codable with Different Array Types
Passing Data from Simple Nsview to Swiftui View
Swift: Can Not Use Array Filter in If Let Statement Condition