我可以嵌入自定义字体的软件包,并从iOS框架访问它?(Can I embed a custom fo

2019-08-16 19:38发布

我创建其包装ressources(笔尖,图片,字体) 捆绑的IOS 框架 ,我试图嵌入束中的自定义字体 ,但我无法从框架加载它,这可能吗?

1)I可以本地化与此字体文件: objc NSString *fontPath = [[NSBundle frameworkBundle] pathForResource:@"MyCustomFont" ofType:@"ttf"]; 2)但我不能让它在我的字体列表: objc NSArray * array = [UIFont familyNames]; 我包括在集合中的一个“由应用程序提供的字体”的plist我的字体名称,没有成功,也试图在应用信息plist中,包括在没有成功的框架的ressource。

我可以从套装(由同捆的名字前缀),而不是字体加载笔尖和图像。 任何想法 ?

编辑:我看到了下面的帖子: 一个iPhone应用程序可以嵌入我自定义字体? ,但问题只是“我可以嵌入自定义字体在iPhone应用程序?” 不是“我可以嵌入在外部框架自定义字体/捆?” 这也使得对动态加载这是有趣的引用,但它使用私有API,这是不是一个框架,可用的解决方案。

谢谢

Answer 1:

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



Answer 2:

下面是我的方式来实现它为我的FMK基于由“大卫M.”提供的解决方案 该解决方案不需要将引用添加到plist中的字体。

1)类加载字体

- (void) loadMyCustomFont{
    NSString *fontPath = [[NSBundle frameworkBundle] pathForResource:@"MyFontFileNameWithoutExtension" 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在您的项目整合



Answer 3:

斯威夫特3:

首先,不要从主访问框架束与附加路径组件......从它的标识符实例化。 你可以得到字体的网址是这样的:

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)
}


Answer 4:

在迅速的,我用下面的代码:

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")

你的更正和言论的欢迎!



Answer 5:

斯威夫特3版@阿里阿巴斯的回答,也更新到了换行选项,而不是力量展开。

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
}


文章来源: Can I embed a custom font in a bundle and access it from an ios framework?