我可以在自定义字体中embedded自定义字体并从ios框架中访问它吗?

我正在创build一个ios 框架捆绑打包资源(笔尖,图像,字体),我试图embedded自定义字体的捆绑,但我不能从框架中加载它,这是可能的吗?

1)我可以本地化字体文件: objc NSString *fontPath = [[NSBundle frameworkBundle] pathForResource:@"MyCustomFont" ofType:@"ttf"]; 2)但我无法得到它在我的字体列表: objc NSArray * array = [UIFont familyNames]; 我把我的字体名称包含在应用程序提供的“字体”的包装中,没有成功,也尝试在应用程序信息plist中,将其包含在框架资源中,但没有成功。

我可以从包中加载nib和图像(通过用包名称作为前缀),但不能加载字体。 任何想法 ?

编辑:我看到以下post: 我可以在iPhone应用程序中embedded自定义字体? ,但问题只是“我可以在iPhone应用程序中embedded自定义字体吗?” 不是“我可以在外部框架/包中embedded自定义字体吗? 它也引用了一个有趣的dynamic加载,但它使用的是私有API,这对框架来说不是可用的解决scheme。

谢谢

这是一种新的方法,可以让你dynamic加载字体,而不用把它们放在你的Info.plist中: http : //www.marco.org/2012/12/21/ios-dynamic-font-loading

这是我根据“David M.”提供的解决scheme为我的fmk实施的方式。 这个解决scheme不需要在plist中添加对字体的引用。

1)加载字体的类

 - (void) loadMyCustomFont{ NSString *fontPath = [[NSBundle frameworkBundle] pathForResource:@"MyFont" ofType:@"ttf"]; NSData *inData = [NSData dataWithContentsOfFile:fontPath]; CFErrorRef error; CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)inData); CGFontRef font = CGFontCreateWithDataProvider(provider); if (! CTFontManagerRegisterGraphicsFont(font, &error)) { CFStringRef errorDescription = CFErrorCopyDescription(error); NSLog(@"Failed to load font: %@", errorDescription); CFRelease(errorDescription); } CFRelease(font); CFRelease(provider); } 

2)NSBundle上的类别可以访问我的包

 + (NSBundle *)frameworkBundle { static NSBundle* frameworkBundle = nil; static dispatch_once_t predicate; dispatch_once(&predicate, ^{ NSString* mainBundlePath = [[NSBundle mainBundle] resourcePath]; NSString* frameworkBundlePath = [mainBundlePath stringByAppendingPathComponent:@"MyBundleName.bundle"]; frameworkBundle = [NSBundle bundleWithPath:frameworkBundlePath]; }); return frameworkBundle; } 

注意:需要将CoreText集成到您的项目中

Swift 3:

首先,不要从main访问框架包,追加path组件…从它的标识符实例化它。 你可以得到像这样的字体url:

 static func fontsURLs() -> [URL] { let bundle = Bundle(identifier: "com.company.project.framework")! let fileNames = ["Roboto-Bold", "Roboto-Italic", "Roboto-Regular"] return fileNames.map({ bundle.url(forResource: $0, withExtension: "ttf")! }) } 

我发现用UIFont扩展名来注册字体是很好的:

 public extension UIFont { public static func register(from url: URL) throws { guard let fontDataProvider = CGDataProvider(url: url as CFURL) else { throw SVError.internal("Could not create font data provider for \(url).") } let font = CGFont(fontDataProvider) var error: Unmanaged<CFError>? guard CTFontManagerRegisterGraphicsFont(font, &error) else { throw error!.takeUnretainedValue() } } } 

现在享受注册:

 do { try fontsURLs().forEach({ try UIFont.register(from: $0) }) } catch { print(error) } 

在swift中,我使用下面的代码:

 public class func loadMyCustomFont(name:String) -> Bool{ let fontPath = self.frameworkBundle().pathForResource(name, ofType: "ttf")! let inData = NSData(contentsOfFile:fontPath) var error: Unmanaged<CFError>? let provider = CGDataProviderCreateWithCFData(inData) if let font = CGFontCreateWithDataProvider(provider) { CTFontManagerRegisterGraphicsFont(font, &error) if error != nil { print(error) //Or logged it return false } } return true } 

frameworkBundle方法:

 class func frameworkBundle() -> NSBundle{ var bundle = NSBundle() var predicate = dispatch_once_t() dispatch_once(&predicate) { let mainBundlePath = NSBundle.mainBundle().bundlePath let frameworkBundlePath = mainBundlePath.stringByAppendingString("/myFramework.framework/") bundle = NSBundle(path: frameworkBundlePath)! } return bundle } 

调用例子:(在我的情况下,我添加了字体文件夹中的所有字体)

 YouClassName.loadMyCustomFont("Fonts/Roboto-Regular") 

您的更正和评论是值得欢迎的!

@Ali-ABBAS的Swift 3版本的答案,也更新为up-wrap选项,而不是强制展开。

 fileprivate func loadCustomFont(name:String) -> Bool{ guard let fontPath = frameworkBundle.path(forResource: name, ofType: "ttf") else { return false } guard let inData = NSData(contentsOfFile:fontPath) else { return false } guard let provider = CGDataProvider(data: inData) else { return false } let font = CGFont(provider) var error: Unmanaged<CFError>? CTFontManagerRegisterGraphicsFont(font, &error) guard error == nil else { print(error) //Or logged it return false } return true }