In my app the User will type anything that he wants and he can make the text Bold, Italic and Underline.
I am able to do the Text - Bold, Italic a
You can enumerate the Attributes with this code (whole range).
[attrStr enumerateAttributesInRange:NSMakeRange(0, [attrStr length]) options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:
^(NSDictionary *attributes, NSRange range, BOOL *stop) {
//Do something here
}
}];
For specific range, your have to change the code NSMakeRange(0, [attrStr lenght])
by the range you need.
After your edit, your specific need, this code should do the work:
[attrStr enumerateAttributesInRange:NSMakeRange(0, [attrStr length])
options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired
usingBlock:
^(NSDictionary *attributes, NSRange range, BOOL *stop)
{
NSMutableDictionary *mutableAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes];
UIFont *currentFont = [mutableAttributes objectForKey: NSFontAttributeName];
UIFont *newFont;
if ([[currentFont fontName] isEqualToString:@"Calibri-BoldItalic"])
newFont = [UIFont fontWithName:@"HelveticaNeue-BoldItalic" size:currentFont.pointSize];
else if ([[currentFont fontName] isEqualToString:@"Calibri-Bold"])
newFont = [UIFont fontWithName:@"HelveticaNeue-Bold" size:currentFont.pointSize];
else if ([[currentFont fontName] isEqualToString:@"Calibri-Italic"])
newFont = [UIFont fontWithName:@"HelveticaNeue-Italic" size:currentFont.pointSize];
[mutableAttributes setObject:newFont forKey:@"NSFont"];
[attrStr setAttributes:mutableAttributes range:range];
}];
From your comments, you may see more complicated things, so I will give you some ideas/tips to do/check. You'll just have to complete my previous code to manage all cases.
• Case: There is no font.
You just have to check if currentFont
is nil. If yes, you set what you want. Since there is no attribute for italic/bold (since they are "included" in the font), I suggest you set for newFont
: HelveticaNeue.
• Case: It's another font than Calibri. There it's quite more complicated.
I've worked with that, and here what I got:
Font name (which is the postscript name
) is made like this for HelveticaNeue (as given example):
HelveticaNeue
HelveticaNeue-Light
HelveticaNeue-UltraLight
HelveticaNeue-Medium
HelveticaNeue-LightItalic
HelveticaNeue-Italic
HelveticaNeue-UltraLightItalic
HelveticaNeue-Bold
HelveticaNeue-BoldItalic
HelveticaNeue-CondensedBold
HelveticaNeue-CondensedBlack
So the first thing you could think of: I just have to check the suffix of the name (with hasSuffix:
). But that may go wrong.
Indeed, some fonts have a foundry suffix (the ones I found are LT, MT, and EF).
Well, for example:
Times New Roman "real name" is TimesNewRomanPSMT.
And its italic version is TimesNewRomanPS-ItalicMT
That's why we have to check if it has a foundry suffix because TimesNewRomanPSMT-Italic won't work (since it doesn't exist, if you try to set a font with this name, it will be nil).
So, as far as I know, and as far I may have some experience and the case I've seen, what you could do:
Check if the [currentFont name]
contains either: BoldItalic
, Italic
or Bold
, using a NSRegularExpression
or a rangeOfString:
. Note that I'd suggest to check before for BoldItalic
since an Italic
may "hides" a Bold
just before it, and Bold
may "hides" an Italic
just after it.
In order to do so, I'd suggest that you create a method like this (or of this style):
-(UIFont)getCorrespondingHelveticaNeueFontMatchingCharacteriticsOf:(UIFont *)font
{
UIFont *helveticaNueue;
if (!font) //Checking if there is a font)
{
helveticaNueue = [UIFont fontWithName@"HelveticaNueue" size:defaultSizeYouSet];
}
else
{
//Check if it's BoldItalic/Italic/Bold
}
return helveticaNueue;
}
checking all the case I mentioned before.
So, from the previous code, you'll just have to replace the if
tests that were working specificly for Calibri with:
UIFont *newFont = [self getCorrespondingHelveticaNeueFontMatchingCharacteriticsOf:currentFont];
Now a third part you may want to do (and add them to your test):
Is the Black
case of a font want to be managed as Bold
? Well, Helvetica Neue
has this "property", but you may want to use directly the black
property for Helvetica Neue
, and may want to check if currentFont
has it (and again, another case).
EDIT:
You can use since iOS7 we can use UIFontDescriptor
. Here is what you could do:
-(UIFont *)customFontMatchingFont:(UIFont *)otherFont
{
NSString *customFontName = @"Helvetica"; //The custom font
UIFont *tempFont = [UIFont fontWithName:customFontName size:[otherFont pointSize]];
return [UIFont fontWithDescriptor:[[tempFont fontDescriptor] fontDescriptorWithSymbolicTraits:[[otherFont fontDescriptor] symbolicTraits]] size:[otherFont pointSize]];
}
Note: I didn't check all the cases (what if your custom family doesn't have a matching font, what does it return? etc.), but that could be a nice add-on if you don't do too complicated things.