Подтвердить что ты не робот

Как конвертировать CGFontRef в UIFont?

Я хочу использовать пользовательский шрифт для UILabel. Пользовательский шрифт загружается из файла:

NSString *fontPath = ... ; // a TTF file in iPhone Documents folder
CGDataProviderRef fontDataProvider = CGDataProviderCreateWithFilename([fontPath UTF8String]);
CGFontRef customFont = CGFontCreateWithDataProvider(fontDataProvider);
CGDataProviderRelease(fontDataProvider); 

Как преобразовать CGFontRef в UIFont, который будет использоваться в [UILabel setFont:]?

4b9b3361

Ответ 1

Ответ Конрада близок, но не совсем работает. Вам нужно предоставить UIFont имя PostScript, а не полное имя.

NSString *fontName = (NSString *)CGFontCopyPostScriptName(fontRef);
UIFont *font = [UIFont fontWithName:fontName size:someSize]

Ответ 2

Вы не можете напрямую преобразовать CGFontRef в UIFont, но вы можете зарегистрировать CGFontRef с помощью CTFontManagerRegisterGraphicsFont, а затем создать соответствующий UIFont.

NSString* fpath = [documentsDirectory stringByAppendingPathComponent:@"custom_font_file_name.ttf"];
CGDataProviderRef fontDataProvider = CGDataProviderCreateWithFilename([fpath UTF8String]);
CGFontRef customFont = CGFontCreateWithDataProvider(fontDataProvider);
CGDataProviderRelease(fontDataProvider);
NSString *fontName = (__bridge NSString *)CGFontCopyFullName(customFont);
CFErrorRef error;
CTFontManagerRegisterGraphicsFont(customFont, &error);
CGFontRelease(customFont);
UIFont* uifont = [UIFont fontWithName:fontName size:12];

Ответ 3

Они, в принципе, не являются напрямую конвертируемыми. Одна простая причина заключается в том, что UIFont инкапсулирует размер шрифта, тогда как CGFont не зависит от размера (размер которого является свойством графического контекста, см. CGContextSetFontSize()).

Предполагая, что вы иначе определили, какой размер шрифта вы хотите, вы должны иметь что-то вроде:

NSString *fontName = (NSString *)CGFontCopyFullName(someCGFontRef);
UIFont *font = [UIFont fontWithName:fontName size:someSize];
[fontName release];

Я действительно не тестировал это, но он должен работать (возможно, с некоторыми незначительными дополнениями). Я считаю, что существует соответствие между именами для CGFont и UIFont, но если их нет, это явно не сработает.

Ответ 4

Вы можете конвертировать CGFont в CTFont, но, к сожалению, ни один из них не получит UIFont. Ниже приведены способы получения UIFont: попросите системный шрифт или попросите шрифт по его имени PostScript. Поэтому для пользовательских шрифтов в UILabel я предлагаю вам использовать последние.

Если вы знаете файл шрифта, которое ваше приложение будет использовать досрочно, вы можете добавить его в свой пакет и загрузить его с помощью UIFont, + fontWithName: size: как UIFont ищет ваш пакет для файла шрифта с этим именем PostScript.

Например, файл шрифта TrueType "VeraMono.ttf" имеет имя PostScript " Bitstream Vera Sans Mono", поэтому он загружается в UILabel, например:

label.font = [UIFont fontWithName:@"Bitstream Vera Sans Mono" size:12];

Чтобы получить имена PostScript нединамически, используйте инструмент шрифта, или, в случае выше, имя PostScript окажется равным отображению "Полное имя" Finder > Get Info.

Однако для случаев, когда вы не обязательно знаете имя шрифта PostScript раньше времени (например, поддерживаете пользовательские шрифты), возможно, вы можете загрузить имя файла в NSData и "grep" для своего имени PostScript...

Удачи,