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

Nic*_*uin 24 frameworks bundle objective-c ios

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

1)我可以使用以下方法对字体文件进行本地化: objc NSString *fontPath = [[NSBundle frameworkBundle] pathForResource:@"MyCustomFont" ofType:@"ttf"]; 2)但我无法在我的字体列表中获取它: objc NSArray * array = [UIFont familyNames]; 我在字符串的plist中包含了我的字体名称,其中包含"应用程序提供的字体",但没有成功,也尝试在app info plist,将其包含在框架资源中但没有成功.

我可以从包中加载笔尖和图像(通过前缀使用包的名称),但不能加载字体.任何想法 ?

编辑:我看到以下帖子:我可以在iPhone应用程序中嵌入自定义字体吗?,但问题只是"我可以在iPhone应用程序中嵌入自定义字体吗?" 不是"我可以在外部框架/捆绑包中嵌入自定义字体吗?" 它还引用了一个有趣的动态加载,但它使用私有api,这对于框架来说不是可用的解决方案.

谢谢

Dav*_* M. 18

这是一种新方法,可让您动态加载字体,而无需将其放入Info.plist中:http://www.marco.org/2012/12/21/ios-dynamic-font-loading


Nic*_*uin 17

这是我根据"David M."提供的解决方案为我的fmk实现的方法.此解决方案不需要在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);
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

注意:需要在项目中集成CoreText


Sta*_*ida 14

斯威夫特3:

首先,不要使用附加路径组件从main访问框架包...从其标识符实例化它.您可以获得如下字体网址:

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")! })
}
Run Code Online (Sandbox Code Playgroud)

我发现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()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在享受注册:

do {
    try fontsURLs().forEach({ try UIFont.register(from: $0) })
} catch {
    print(error)
}
Run Code Online (Sandbox Code Playgroud)