18

この質問が何度も尋ねられ、回答されているのを見てきましたが、本当の答えを見たことがありません. 一般的な「解決策」は次のとおりです。

  • フォントをアプリケーション バンドルに追加し、info.plist ファイルに登録します。
  • カスタム フォントの解析およびレンダリング ライブラリ (Zynga のFontLabel など) を使用します。
  • それはできません。

問題は、iOS でフォ​​ントを動的にロードする方法です。 フォントを「動的に」ロードするということは、アプリのコンパイル時には不明な特定のフォントをロードすることを意味します。

4

6 に答える 6

25

フォントは、任意の場所または任意のバイト ストリームから簡単に動的にロードできます。こちらの記事を参照してください: http://www.marco.org/2012/12/21/ios-dynamic-font-loading

NSData *inData = /* your font-file data */;
CFErrorRef error;
CGDataProviderRef provider = CGDataProviderCreateWithCFData((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);
  • フォントをバンドルに入れる必要はありません。
  • info.plist にフォントを明示的に登録する必要はありません。

参照: https://developer.apple.com/library/mac/#documentation/Carbon/Reference/CoreText_FontManager_Ref/Reference/reference.html#//apple_ref/doc/uid/TP40008278

https://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/CGFont/Reference/reference.html#//apple_ref/c/func/CGFontCreateWithDataProvider

于 2012-12-27T02:07:25.493 に答える
9

Marco からの最近の記事Loading iOS fonts dynamic をお楽しみください。

NSData *inData = /* your decrypted font-file data */;
CFErrorRef error;
CGDataProviderRef provider = CGDataProviderCreateWithCFData((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);
于 2012-12-27T04:01:46.930 に答える
2

Swift 3の@ mt81の更新された回答は次のとおりです。

guard
    let path = "Path to some font file",
    let fontFile = NSData(contentsOfFile: path)
else {
    print "Font file not found?"
}

guard let provider = CGDataProvider(data: fontFile)
else {
    print "Failed to create DataProvider"
}

let font = CGFont(provider)
let error: UnsafeMutablePointer<Unmanaged<CFError>?>? = nil

guard CTFontManagerRegisterGraphicsFont(font, error) else {
    guard
        let unError = error?.pointee?.takeUnretainedValue(),
        let description = CFErrorCopyDescription(unError)
    else {
        print "Unknown error"
    }
    print description
}
于 2017-09-04T13:32:03.750 に答える
2

サーバーから TTF ファイルをダウンロードしていますか?

TTF ファイルをダウンロードしている場合は、次のようにしてカスタム フォントを iOS フォント マネージャーに登録できます。このコードは、TTF ファイルの更新(フォントの更新)も処理します。

+(void)registerFontsAtPath:(NSString *)ttfFilePath
{
    NSFileManager * fileManager = [NSFileManager defaultManager];

    if ([fileManager fileExistsAtPath:ttfFilePath] == YES)
    {
        [UIFont familyNames];//This is here for a bug where font registration API hangs for forever.

        //In case of TTF file update : Fonts are already registered, first de-register them from Font Manager
        CFErrorRef cfDe_RegisterError;
       bool fontsDeregistered = CTFontManagerUnregisterFontsForURL((__bridge CFURLRef)[NSURL fileURLWithPath:ttfFilePath], kCTFontManagerScopeNone, &cfDe_RegisterError);


        //finally register the fonts with Font Manager,
        CFErrorRef cfRegisterError;
        bool fontsRegistered= CTFontManagerRegisterFontsForURL((__bridge CFURLRef)[NSURL fileURLWithPath:ttfFilePath], kCTFontManagerScopeNone, &cfRegisterError);
}
于 2017-01-07T17:00:27.557 に答える
2
// Note : add "CoreText.framework" into your project to support following code

// Put loadCustomFont function inside app delegate or any shared class to access any where in code...

    -(void)loadCustomFont:(NSMutableArray *)customFontFilePaths{

        for(NSString *fontFilePath in customFontFilePaths){

            if([[NSFileManager defaultManager] fileExistsAtPath:fontFilePath]){

                NSData *inData = [NSData dataWithContentsOfFile:fontFilePath];
                CFErrorRef error;
                CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)inData);
                CGFontRef font = CGFontCreateWithDataProvider(provider);
                // NSString *fontName = (__bridge NSString *)CGFontCopyFullName(font);
                if (!CTFontManagerRegisterGraphicsFont(font, &error)) {
                    CFStringRef errorDescription = CFErrorCopyDescription(error);
                    NSLog(@"Failed to load font: %@", errorDescription);
                    CFRelease(errorDescription);
                }
                CFRelease(font);
                CFRelease(provider);
            }
        }
    }

    // Use as follow inside your view controller...

    - (void)viewDidLoad
    {
        [super viewDidLoad];

        // pass all font files name into array which you want to load dynamically...
        NSMutableArray *customFontsPath = [[NSMutableArray alloc] init];
        NSArray *fontFileNameArray = [NSArray arrayWithObjects:@"elbow_v001.ttf",@"GothamRnd-MedItal.otf", nil];

        for(NSString *fontFileName in fontFileNameArray){

            NSString *fileName = [fontFileName stringByDeletingPathExtension];
            NSString *fileExtension = [fontFileName pathExtension];
            [customFontsPath addObject:[[NSBundle mainBundle] pathForResource:fileName ofType:fileExtension]];
        }


        AppDelegate *appDel = (AppDelegate *)[[UIApplication sharedApplication] delegate];
        // load custom font into memory...
        [appDel loadCustomFont:customFontsPath];

        // Use font as below
        [lblName setFont:[UIFont fontWithName:@"Elbow v100" size:15.0]];
        [lblName2 setFont:[UIFont fontWithName:@"Gotham Rounded" size:20.0]];
    }
于 2013-05-07T06:49:34.050 に答える