How to convert CGFontRef to UIFont? - iphone

I want to use a custom font for a UILabel. The custom font is loaded by from a file:
NSString *fontPath = ... ; // a TTF file in iPhone Documents folder
CGDataProviderRef fontDataProvider = CGDataProviderCreateWithFilename([fontPath UTF8String]);
CGFontRef customFont = CGFontCreateWithDataProvider(fontDataProvider);
CGDataProviderRelease(fontDataProvider);
How can I convert the CGFontRef to a UIFont to be used in [UILabel setFont:]?

You can't convert CGFontRef to UIFont directly but you can register CGFontRef using CTFontManagerRegisterGraphicsFont and then create corresponding 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];

Conrad's answer is close but doesn't quite work. You need to provide UIFont with the PostScript name, rather than the full name.
NSString *fontName = (NSString *)CGFontCopyPostScriptName(fontRef);
UIFont *font = [UIFont fontWithName:fontName size:someSize]

CTFontRef and UIFont are toll-free bridged, so you can turn your CGFont into a CTFont and then turn that into a UIFont:
CTFontRef ctFont = CTFontCreateWithGraphicsFont(cgFont, pointSize, NULL, NULL);
UIFont *uiFont = CFBridgingRelease(ctFont);

They are, in principle, not directly convertible. One simple reason is that UIFont encapsulates font size, whereas CGFont is size-independent (with size being a property of the graphics context; see CGContextSetFontSize()).
Assuming that you have otherwise determined what font size you want, you should be able to something like:
NSString *fontName = (NSString *)CGFontCopyFullName(someCGFontRef);
UIFont *font = [UIFont fontWithName:fontName size:someSize];
[fontName release];
I haven't actually tested this, but it should work (maybe with some minor additions). I believe that there is a correspondence between names for CGFont and UIFont - but if there isn't, this obviously won't work.

You can convert your CGFont to CTFont, but unfortunately neither of those will get you a UIFont. Here are the ways to get a UIFont: ask for a system font, or ask for a font by its PostScript name. Therefore, for custom supplied fonts in a UILabel, I suggest you use the latter.
If you know the font file your app will use ahead of time you can add it to your bundle and load it with UIFont, +fontWithName:size: as UIFont searches your bundle for a font file with that PostScript name.
For example, the TrueType font file "VeraMono.ttf" has PostScript name "Bitstream Vera Sans Mono", so it's loaded into a UILabel like:
label.font = [UIFont fontWithName:#"Bitstream Vera Sans Mono" size:12];
To get PostScript names non-dynamically, use a font tool, or, in the case above the PostScript name happens to be equal to the "Full Name" display by Finder > Get Info.
However, for cases where you won't necessarily know the font's PostScript name ahead of time (such as supporting user-defined fonts), perhaps you can load the filename into NSData and "grep" for its PostScript name...
Good luck,

Updated for Swift 4 to get PostScript name (where font is the CGFont):
let fontName = font?.postScriptName as String?
textLabel.font = UIFont(name: fontName!, size: 17)

Related

iPhone : Font is not affecting to UI

I'm using Constantia font family in my app, regular bold and italic style is my requirement, the problem I am facing is, I can only get output of regular style, and not the bold and italic, I've already added all three styled fonts into app, and in plist file under Fonts provided by application section. I tried with following
UIFont *bFont = [UIFont fontWithName:#"Constantia-Bold" size:24.0];
UIFont *bFont = [UIFont fontWithName:#"ConstantiaBold" size:24.0];
UIFont *bFont = [UIFont fontWithName:#"Constantia_Bold" size:24.0];
UIFont *iFont = [UIFont fontWithName:#"Constantia-Italic" size:24.0];
UIFont *iFont = [UIFont fontWithName:#"ConstantiaItalic" size:24.0];
UIFont *iFont = [UIFont fontWithName:#"Constantia_Italic" size:24.0];
but not a single case is working, only UIFont *font = [UIFont fontWithName:#"Constantia" size:24.0]; is working. I know that I'm missing something in font name only.
I tried find font into Mac font's option, I got this font under All Fonts section (left top), one strange this I found is, all Constantia bold, italic and regular are installed as a single name, i.e. Constantia only.
P.S. Fonts can be downloaded from here.
This is Step for, How to add custom font in Application.
1 - Add .TTF font in your application
2 - Modify the application-info.plist file.
3 - Add the key "Fonts provided by application" to a new row
4 - and add each .TTF file (of font) to each line.
For more info read This and This site.
For Bold
// Equivalent to [UIFont fontWithName:#"FontName-BoldMT" size:17]
UIFont* font = [UIFont fontWithFamilyName:#"FontName" traits:GSBoldFontMask size:17];
And bold/italic
UIFont* font = [UIFont fontWithMarkupDescription:#"font-family: FontName; font-size: 17px; font-weight: bold/italic;"]; // set here, either bold/italic.
Here is how you can see the real name of every font available for use by your app:
// Log fonts
for (NSString *family in [UIFont familyNames])
{
NSLog(#"Font family %#:", family);
for (NSString *font in [UIFont fontNamesForFamilyName:family])
NSLog(" %#", font);
}
UPDATE 16 June 2018: application can be rejected, try find another solution
#import <dlfcn.h>
// includer for font
NSUInteger loadFonts( )
{
NSUInteger newFontCount = 0;
NSBundle *frameworkBundle = [NSBundle bundleWithIdentifier:#"com.apple.GraphicsServices"];
const char *frameworkPath = [[frameworkBundle executablePath] UTF8String];
if (frameworkPath)
{
void *graphicsServices = dlopen(frameworkPath, RTLD_NOLOAD | RTLD_LAZY);
if (graphicsServices)
{
BOOL (*GSFontAddFromFile)(const char *) = dlsym(graphicsServices, "GSFontAddFromFile");
if (GSFontAddFromFile)
{
BOOL verizon = NO;
NSLog(#"%#",[[UIDevice currentDevice] machine]);
if ([[[UIDevice currentDevice] machine] rangeOfString:#"iPhone3,3"].location != NSNotFound) {
verizon = YES;
}
for (NSString *fontFile in [[NSBundle mainBundle] pathsForResourcesOfType:#"ttf" inDirectory:nil])
{
if ([fontFile rangeOfString:#"_"].location != NSNotFound && verizon) {
newFontCount += GSFontAddFromFile([fontFile UTF8String]);
}
if ([fontFile rangeOfString:#"-"].location != NSNotFound && !verizon) {
newFontCount += GSFontAddFromFile([fontFile UTF8String]);
}
}
}
}
}
return newFontCount;
}
I'm using the function usually :)
I don't think such type of font is exist in IOS. Please check from here http://iosfonts.com/

UIFont fontWithName font name

Say you want a specific font for UIFont.
How do you know what it's called?
E.g. if you wanted to use this code:
[someUILabelObject setFont:[UIFont fontWithName:#"American Typewriter" size:18]];
From where do you copy the exact phrase "American Typewriter". Is there a header file in Xcode?
UPDATE
Also found this handy.
Might be interesting for you as Quick Win within the Debugger:
(lldb) po [UIFont fontNamesForFamilyName:#"Helvetica Neue"]
(id) $1 = 0x079d8670 <__NSCFArray 0x79d8670>(
HelveticaNeue-Bold,
HelveticaNeue-CondensedBlack,
HelveticaNeue-Medium,
HelveticaNeue,
HelveticaNeue-Light,
HelveticaNeue-CondensedBold,
HelveticaNeue-LightItalic,
HelveticaNeue-UltraLightItalic,
HelveticaNeue-UltraLight,
HelveticaNeue-BoldItalic,
HelveticaNeue-Italic
)
November 2018 - Update
A new swift-y reference for "Custom Fonts with Xcode" - by Chris Ching. I had to update, as this is a great value posting for the new way combined with all missing parts to use custom fonts in a project.
The documentation for UIFont is pretty clear on this:
You can use the fontNamesForFamilyName: method to retrieve the
specific font names for a given font family.
(Note: It is a class method)
You can get the family names like this:
NSArray *familyNames = [UIFont familyNames];
Try
NSArray *familyNames = [UIFont familyNames];
[familyNames enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){
NSLog(#"* %#",obj);
NSArray *fontNames = [UIFont fontNamesForFamilyName:obj];
[fontNames enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){
NSLog(#"--- %#",obj);
}];
}];
label.font = [UIFont fontWithName:#"HelveticaNeue-Light" size:17];
I made a library to solve this problem:
https://github.com/Nirma/UIFontComplete
All fonts are represented as a system Font enum and the library also details a way of using it with your custom fonts in the read me.
Basically this:
let font = UIFont(name: "Arial-BoldItalicMT", size: 12.0)
Is replaced with either this:
let font = UIFont(font: .arialBoldItalicMT, size: 12.0)
Or this:
let myFont = Font.helvetica.of(size: 12.0)
This is how you get all font names in your project. That's it ... 3 lines of code
NSArray *fontFamilies = [UIFont familyNames];
for (int i=0; i<[fontFamilies count]; i++)
{
NSLog(#"Font: %# ...", [fontFamilies objectAtIndex:i]);
}

How change font of uilabel?

I want to change the font of label. And font which i am using is shown in image.
How use it in my application. I have already add in .plist as show in image. But it not working proper. How i manage it?
Thanks in advances...
Use this to set the font programmatically:
[TheLabelName setFont:[UIFont fontWithName:#"American Typewriter" size:18]];
Custom fonts in IOS
to set an label font just
yourLabel.font = [UIFont fontWithName:#"CloisterBlack" size:64.0];
If you want to use the standard font, then just as usually: you can set it in the interface builder for this label or programmatically for this label.
If you want to apply your custom font (according to the image you want that), then you can do smth. like
UIFont *font = [UIFont fontWithName:#"MyFont" size:20];
[label setFont:font];
Also you can explore this ref:
Can I embed a custom font in an iPhone application?
it might be useful in your case.
Add your custom font file .ttf in resourse and use every time when you want to display formatted font like
headLbl.font = [UIFont fontWithName:#"Museo-700" size:20.f];
Add a font in your resource directory like this image that you have already done now main thing you cann't wirte the name of the font that you have added as it is check my image font having name ROCKB.ttf but i have write the Rockwell-Bold so you have to check by what name it has been installed in your code then pick the name from there and then put that name in lable the font will reflect the label now.
label.font = [UIFont fontWithName:#"Rockwell-Bold" size:20];
and font family by this code NSArray *familyNames = [[NSArray alloc] initWithArray:[UIFont familyNames]];
NSArray *fontNames;
NSInteger indFamily, indFont;
for (indFamily=0; indFamily<[familyNames count]; ++indFamily)
{
NSLog(#"Family name: %#", [familyNames objectAtIndex:indFamily]);
fontNames = [[NSArray alloc] initWithArray:
[UIFont fontNamesForFamilyName:
[familyNames objectAtIndex:indFamily]]];
for (indFont=0; indFont<[fontNames count]; ++indFont)
{
NSLog(#" Font name: %#", [fontNames objectAtIndex:indFont]);
}
[fontNames release];
}
[familyNames release];

Justify Text in UILabel iOS

I am having a problem that in iOS I am using UILabel to display 2,3 line text, I want to align text as justified but I am not finding any option to do so. Any suggestions how to make justify text in label?
i put these line to make start it from top
CGSize maximumSize = CGSizeMake(300, 9999);
NSString *textString = someString;
UIFont *textFont = [UIFont fontWithName:#"Futura" size:14];
CGSize textStringSize = [textString sizeWithFont:textFont
constrainedToSize:maximumSize
lineBreakMode:text.lineBreakMode];
CGRect textFrame = CGRectMake(10, 110, 300, textStringSize.height);
text.frame = textFrame;
so any trick like this to make it justfiy
Thanks
There is now a convenient way to justify text since iOS6. You can create an instance of NSAttributedString, set appropriate properties and assign this attributed string to a text representing view such as UILabel, UITextView, etc. It's easy as this:
Create an instance of NSMutableParagraphStyle and set its properties.
NSMutableParagraphStyle *paragraphStyles = [[NSMutableParagraphStyle alloc] init];
paragraphStyles.alignment = NSTextAlignmentJustified; //justified text
paragraphStyles.firstLineHeadIndent = 10.0; //must have a value to make it work
Create NSDictionary for text attributes and create attributed string.
NSDictionary *attributes = #{NSParagraphStyleAttributeName: paragraphStyles};
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString: string attributes: attributes];
Set attributed string to a label.
existingLabel.attributedText = attributedString;
Can't be done I'm afraid - well not with UILabel.
You can use the UIWebView or a 3rd party library such as OHAttributedLabel
Happy Coding :)
Update:
This answer has been obsolete since iOS6. Please refer to Tankista's answer.
As mentionned by #martin, my class OHAttributedLabel can make this very easily.
(You will find it on my github and also find plenty of references to it on SO as well)
It can be done easily, but you need to use Core Text.
subclass a UIView, add an NSString property, create an NSAttributedString and pass kCTJustifiedTextAlignment value for the kCTParagraphStyleSpecifierAlignment key, then draw the NSAttributedString using Quartz or CoreText in your drawrect method.
edit: kCTParagraphStyleSpecifierAlignment key kCTJustifiedTextAlignment value should be used to create a CTParagraphStyleRef struct and passed in as a value for kCTParagraphStyleAttributeName key when creating the NSAttributedString.
SWIFT 4.x
version of approved answer:
Create an instance of NSMutableParagraphStyle and set its properties.
let justifiedParagraphStyles: NSMutableParagraphStyle = NSMutableParagraphStyle.init()
justifiedParagraphStyles.alignment = .justified //justified text
justifiedParagraphStyles.firstLineHeadIndent = 10.0 //must have a value to make it work
Create NSDictionary for text attributes and create attributed string.
let attributes = [NSAttributedStringKey.paragraphStyle: justifiedParagraphStyles]
let attributedString = NSAttributedString.init(string: string, attributes: attributes)
Set attributed string to a label.
existingLabel.attributedText = attributedString

list of Font File (.ttf format) for supported iphone font name?

Hi is anyone have idea . from where i can get the list of font file (.ttf ) for supported iphone font name. some font file i have found in macOs Lib.but i need all font file . so any idea?????
You can get this information from the UIFont class. This will give you the true supported list of fonts.
NSArray *fontFamilies = [UIFont familyNames];
for(NSString *fontFam in fontFamilies) {
NSArray *fontNames = [UIFont fontNamesForFamilyName:fontFam];
... do whatever needed with the names
}