Как конвертировать CGFontRef в UIFont? - PullRequest
14 голосов
/ 09 февраля 2012

Я хочу использовать пользовательский шрифт для 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:]?

Ответы [ 6 ]

15 голосов
/ 19 сентября 2012

Вы не можете конвертировать 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];
15 голосов
/ 12 июля 2012

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

NSString *fontName = (NSString *)CGFontCopyPostScriptName(fontRef);
UIFont *font = [UIFont fontWithName:fontName size:someSize]
3 голосов
/ 09 февраля 2012

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

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

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

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

2 голосов
/ 09 февраля 2012

Вы можете конвертировать ваш 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 ...

Удачи,

1 голос
/ 12 марта 2018

CTFontRef и UIFont являются бесплатными мостами , так что вы можете превратить ваш CGFont в CTFont, а затем превратить его в UIFont:

CTFontRef ctFont = CTFontCreateWithGraphicsFont(cgFont, pointSize, NULL, NULL);
UIFont *uiFont = CFBridgingRelease(ctFont);
0 голосов
/ 12 марта 2018

Обновлено для Swift 4 для получения имени PostScript (где font - это CGFont):

let fontName = font?.postScriptName as String?
textLabel.font = UIFont(name: fontName!, size: 17)
...