how to make font bold,unbold of any font style - ios

Can anybody please explain how can we make any font family font, bold or unbold + Italic or Non Italic + Underlined or Non underLined. Everywhere I got the method that make the changes but on system font. I even tried giving 2 attributes to NSAttributed string
1. Bold
2. A font family from list of supported font family
But it didnt work. Thanks in Advance.

try this
UIFontDescriptor *fontDescriptor = [[UIFontDescriptor alloc] init];
UIFontDescriptor *fontDescriptorForHelveticaNeue = [fontDescriptor fontDescriptorWithFamily:#"Helvetica Neue"];
UIFontDescriptor *symbolicFontDescriptor = [fontDescriptorForHelveticaNeue fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold];
UIFontDescriptor *symbolicFontDescriptor1 = [fontDescriptorForHelveticaNeue fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitMonoSpace];
NSString *text = #"iOS 7";
if(some condition){
CGSize fontSize = [text sizeWithAttributes:#{NSFontAttributeName:[UIFont fontWithDescriptor:symbolicFontDescriptor size:17.0f]}];
}
else{
CGSize fontSize = [text sizeWithAttributes:#{NSFontAttributeName:[UIFont fontWithDescriptor:symbolicFontDescriptor1 size:17.0f]}];
}

You can't do it with a few lines of code. A normal font and its bold version are completely separated (ie they're like two unrelated fonts), and if you have a look at iosfonts, the naming is not consistent. Some fonts don't have bold version, and some have several bold versions!
A solution (that requires a bit of effort, but surely works): create a list of pairs of font names, like this
{"ArialHebrew", "ArialHebrew-Bold"},
{"AvenirNext-Regular", "AvenirNext-Bold"},
...
And populate the list of fonts with the regular version (the left one). If the user desires to make it bold, then switch to the bold version (the right one).
My recommendation is to limit the number of choices for user (as iOS always does): you don't need to copy the whole list from iosfonts! just some popular ones are enough.

This may not be sufficiently generic for your purses, but maybe it'll help someone else
+ (UIFont *)whateverInvertedBoldnessFontFromFont:(UIFont *)font pointSize:(CGFloat)pointSize
{
NSString *customFontFamilyName = #"Whatever";
NSString *ibFontName = font.fontName;
NSString *customFontStyle = nil;
if ([ibFontName rangeOfString:#"Bold"].location != NSNotFound) {
customFontStyle = #"Regular";
}
else {
customFontStyle = #"Bold";
}
UIFont *customFont = [UIFont fontWithName:[NSString stringWithFormat:#"%#-%#", customFontFamilyName, customFontStyle] size:pointSize];
return customFont;
}
unfortunately this is quite fragile and works reliably when the source and destination
font families are known

If you want to set it programmatically, you must check with the font supported by xCode (iOS).
and if you want to do bold to any font then you have to use :
UIFont* boldFont = [UIFont boldSystemFontOfSize:[UIFont systemFontSize]];
[myLabel setFont:boldFont];
where myLabel is your label name.

Related

Detecting light fonts in iOS

I am trying to specify the font family of every label in my iOS app in a way that makes it fairly easy to change them later. I don't want to have to go through Interface Builder and reset every font on every screen. According to this post, I have created a method that will find all the fonts in a view and set them accordingly.
In my case, there are a few different font families I need to use based on whether the font is bold, italic, or light (e.g. skinny). These are all located in separate files such as "OpenSans-Semibold.ttf", "OpenSans-Italic.ttf", and "OpenSans-Light.ttf".
Ideally, I would like to be able to set the font to bold, italic, or light in Interface Builder, then have the code override just the font family, using the appropriate .ttf file. According to this post, I can pretty easily detect whether the font has been set to bold or italic, but finding out whether it's light or not doesn't seem to be working.
For the light fonts, the value of "traits" is 0x0--so no flags are set. Is there another way to detect light fonts?
Code looks like this:
- (void) setFontFamily:(UIView*)view
{
if([view isKindOfClass:[UILabel class]])
{
UILabel* label = (UILabel*)view;
UIFontDescriptorSymbolicTraits traits = label.font.fontDescriptor.symbolicTraits;
BOOL bold = traits & UIFontDescriptorTraitBold;
BOOL italic = traits & UIFontDescriptorTraitItalic;
if(bold)
[label setFont:[UIFont fontWithName:#"OpenSans-Semibold"size:label.font.pointSize]];
else if(italic)
[label setFont:[UIFont fontWithName:#"OpenSans-Italic"size:label.font.pointSize]];
else if(light)
[label setFont:[UIFont fontWithName:#"OpenSans-Light"size:label.font.pointSize]];
else
[label setFont:[UIFont fontWithName:#"OpenSans"size:label.font.pointSize]];
}
for(UIView* subView in view.subviews)
[self setFontFamily:subView];
}
Your entire approach to determining a font based on its characteristics is problematic:
else if(italic)
[label setFont:
[UIFont fontWithName:#"OpenSans-Italic"size:label.font.pointSize]];
You are hard-coding the font name based on the trait. Instead, ask the runtime for the font based on the name and trait. In this very simple example I find out what installed font, if any, is an italic variant of Gill Sans:
UIFont* f = [UIFont fontWithName:#"GillSans" size:15];
CTFontRef font2 =
CTFontCreateCopyWithSymbolicTraits (
(__bridge CTFontRef)f, 0, nil,
kCTFontItalicTrait, kCTFontItalicTrait);
UIFont* f2 = CFBridgingRelease(font2);
Note that this code is valid in iOS 7 only, where CTFontRef and UIFont are toll-free bridged to one another. In theory it should be possible to do this without C functions through UIFontDescriptor, but the last time I looked it was buggy and didn't work for all fonts (e.g. Gill Sans!).
That is what you should be doing: determine the symbolic and weight traits of your starting font, and then ask the runtime for the font that most close matches your requirements.

Adding bold to a UILabel

I'm trying to figure out how to best bold and un-bold a UILabel with a font that was defined in the Interface Builder.
I know I can do this, for example:
[myLabel setFont:[UIFont boldSystemFontOfSize:14.0]];
But then I'm forcing the font to potentially different (both in style and size) than the way it was designed in IB.
I'm looking for something that essentially does this:
[myLabel setBold:TRUE];
or False, as the case may be.
Is there a way to do this?
Unfortunately, there's no real concept of "Bold" in UIKit. If you ever try setting part of an attributed string to "Bold", you are actually selecting the bold font variant in the same font family.
You could so something semihackish like this:
#implementation UIFont (BoldVariant)
- (UIFont *)boldVariant
{
for (NSString *fontName in [UIFont fontNamesForFamilyName:self.familyName]) {
if ([fontName hasSuffix:#"-Bold"]) {
return [UIFont fontWithName:fontName size:self.pointSize];
}
}
// If we couldn't find it, return the same font.
return self;
}
#end
This assumes that the font follows the standard naming scheme. It also assumes that fontNamesForFamilyName: returns any values. I noticed that with the system font, it returns an empty array.
If you are using for example system font which is Helvetica you can make the label.text bold like this:
myLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size:14];
You can find iOS fonts for example in this site: link
You want an approach that works regardless of the font that is in place in your label, so it works with multiple labels?
How about this?
Fetch the current font from the label using it's font property.
Get the font family name for that font.
Ask the font family for it's list of fonts using the UI fontNamesForFamilyName.
See if you can find a bold font in the list of fonts you get back. If so, request that font at your current font size. If not, use the bold system font at the current size. (You might have to string parse the font names looking for the word "bold" in the name. Ugh.)
Not ideal, but you should be able to make it work.
I was able to find nice and clear solution:
extension UIFont {
/// Returns same font but with specific `symbolicTraits`.
func with(symbolicTraits: UIFontDescriptor.SymbolicTraits) -> UIFont {
let descriptor = fontDescriptor.withSymbolicTraits(symbolicTraits) ?? fontDescriptor
return UIFont(descriptor: descriptor, size: pointSize)
}
}
Usage:
label.font = label.font.with(symbolicTraits: .traitBold)
Or if you want to mix multiple traits:
label.font = label.font.with(symbolicTraits: [.traitBold, .traitItalic) // returns same font (name and size) but is bold and italic.

How to tell which iOS font name is the "regular" version in a font family?

I know that I can get a list of font family names with [UIFont familyNames] and iterate through the family's font names with [UIFont fontNamesForFamilyName:]. Is there any way to tell which font name represents the "normal" font? There isn't any consistency in the naming ("Roman", "Regular", or even the absence of a modifier adjective). I'm ultimately trying to change the font over a substring of an NSAttributedString while maintaining existing traits and decorations. Thanks in advance.
Well, I need to read the CoreText docs more closely. Passing in the font family name is enough if you use the right CoreText routines...
NSString *fontFamilyName = ...(font family name)...;
// Make a mutable copy of the attributed text
NSMutableAttributedString *workingAttributedText = [self.attributedText mutableCopy];
// Over every attribute run in the selected range...
[workingAttributedText enumerateAttributesInRange:self.selectedRange
options:(NSAttributedStringEnumerationOptions) 0
usingBlock:^(NSDictionary *attrs, NSRange range, BOOL *stop) {
// get the old font
CTFontRef oldFont = (__bridge CTFontRef)[attrs objectForKey:NSFontAttributeName];
// make a new one, with our new desired font family name
CTFontRef newFontRef = CTFontCreateCopyWithFamily(oldFont, 0.0f, NULL, (__bridge CFStringRef)fontFamilyName);
// Convert it to a UIFont
UIFont *newFont = [UIFont fontWithCTFont:newFontRef];
// Add it to the attributed text
[workingAttributedText addAttribute:NSFontAttributeName value:newFont range:range];
}];
// Replace the attributed text with the new version
[self setAttributedText:workingAttributedText];
If there is an easier way to do this, I'd love to hear about it.
There doesn't have to be a regular font in the list. Some may only provide bold or only italic. This is why the list is often provided to the user to let them make the decision.

how to change the style of the font programmatically in objective-c

I would like to change the style of the font (like bold, regular, light, oblique) programmatically. I know I can use the IB, but I would like to change it using programmatically. Need some guidance on this. Sorry if it is a stupid question.
For example, my code looks like this:
lblAge.font = [UIFont fontWithName:#"Helvetica" size:20];
I would like to add the style which is regular in. How do I it?
This should get you going
offerTitle.font = [UIFont fontWithName:#"TimesNewRomanPS-ItalicMT" size:14.0f];//here offerTitle is the instance of `UILabel`
Hope this helps:)
Try this solution:
myLabel.font = [UIFont boldSystemFontOfSize:16.0f];
myLabel.font = [UIFont italicSystemFontOfSize:16.0f];
For regular size:
myLabel.font = [UIFont systemFontOfSize:16.0f];
Hope it helps you.
For iOS 8.2 and above there is + systemFontOfSize:weight: which allows you to specify weighted system fonts.
Look at API of UIFont. Assign created font to the property 'font' of designated object
oneLabel.font=[UIFont fontWithXXX];
static NSString *_myCustomFontName;
+ (NSString *)myCustomFontName:(NSString*)fontName{
if ( !_myCustomFontName ){
NSArray *arr = [UIFont fontNamesForFamilyName:fontName];
// I know I only have one font in this family
if ( [arr count] > 0 )
_myCustomFontName = arr[0];
}
return _myCustomFontName;
}

How to make a UIFont bold or italic?

Having a UILabel with any font, how can I find out if it is already bold? Or how can I make it bold? In CSS, I have a font-weight attribute. I would like to have something similar.
Everything I found out so far is that you have to set the proper font name. However, this is unreliable. The bold version of Cochin is Cochin-Bold, but the bold version of ArialMT is not ArialMT-Bold but Arial-BoldMT, so it obviously does not suffice to append -Bold. (The bold version of a custom font could also have a totally different name).
What I can do is finding all fonts for the family of my given font.
__block UIFont *font = myLabel.font;
[[UIFont fontNamesForFamilyName:font.familyName] enumerateObjectsUsingBlock:^(NSString *fontName, NSUInteger idx, BOOL *stop) {
if ([fontName rangeOfString:#"bold" options:NSCaseInsensitiveSearch].location != NSNotFound) {
font = [UIFont fontWithName:fontName size:font.pointSize];
*stop = YES;
}
}];
myLabel.font = font;
But this does not work reliably. I can easily get a BoldItalic version. I could improve my check to avoid this, but it is not really a good solution.
Maybe CoreText can help here?
Maybe CoreText can help here?
CoreText uses its own font system, CTFont. If you're using that, you can do what you want:
CTFontRef font = CTFontCreateWithName((__bridge CFStringRef)name, size, NULL);
CTFontRef boldFont = CTFontCreateCopyWithSymbolicTraits(font, 0.0, NULL, kCTFontBoldTrait, kCTFontBoldTrait);
I suppose you could then get the name of the derived bold font:
CFStringRef boldName = CTFontCopyPostScriptName(boldFont);
...and use it to create a new UIFont:
UIFont *ret = [UIFont fontWithName:(NSString *)boldName size:size];
I don't know how quick this would be, but you could do it on app launch then cache the names.
Introduced with iOS 7, UIFontDescriptor is the tool for doing this.
To find out if the font is already bold, get the UIFontDescriptor of your font (via UIFont's fontDescriptor property), then call symbolicTraits, and inspect the resulting bitmask for UIFontDescriptorTraitBold.
Likewise, to find a bold version, take the font descriptor for the original font, and call - fontDescriptorWithSymbolicTraits:. You can then turn it back into a UIFont by calling + [UIFont fontWithDescriptor:size:].
UIFontDescriptorSymbolicTraits symbolically describes stylistic aspects of a font. The upper 16 bits is used to describe appearance of the font whereas the lower 16 bits for typeface. The font appearance information represented by the upper 16 bits can be used for stylistic font matching.
Swift 3
extension UIFont {
convenience init?(name: String, size: CGFloat, symbolicTraits: UIFontDescriptorSymbolicTraits) {
guard let descriptor = UIFontDescriptor(name: name, size: size).withSymbolicTraits(symbolicTraits) else { return nil }
self.init(descriptor: descriptor, size: size)
}
}

Resources