Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can we set NSFont's font-weight or font-style directly, instead of changing the font name?

Tags:

ios

styling

fonts

The question up front:

Can we directly access the font-weight and font-style information for an attributed string? Or can we create a new string for which we are able to set this information?

The explanation:

In iOS 6, you can toggle a selection as bold or italic. But the way this works is vexing: it does not change the NSFontAttributeName that Apple has exposed to us (changing the font name from, for instance, "HelveticaNeue" to "HelveticaNeue-Bold"). Instead, it preserves the font-family as "Helvetica Neue" and changes the "font-weight" to bold in the style string. If you were to ask an instance of attributed text for its description, you would see something like this for its font information:

NSFont = "<UICFFont: 0x1fbc53a0> font-family: \"Helvetica Neue\"; font-weight: bold; font-style: normal; font-size: 16px";

This creates a problem. We cannot change the font while preserving bold and italic style information. If you jump through the hoops of scanning the old attributed string for style info, creating a new string with a new font, and then changing the font attribute name (using, for instance, "Courier-Bold" for everywhere you want it to be bold), you create a new problem: if you try to toggle the font back to normal (not bold) you will instead have a font name like "Courier-Bold" AND a font-weight of "bold", because the style information was not yet set to bold. And toggling will not, of course, change the font name. So you've essentially created a font that can no longer be changed when the user toggles the selected text. The user will press the "bold" button in the contextual menu, but it will do nothing, because the boldness has now been hardcoded into the font name, you might say.

If you go the other route and try to override "toggleBoldface" and "toggleItalic" in your UITextView, it does not seem possible to actually prevent the style information in the style string from being changed. You cannot, it seems, change the font name alone during the toggle event.

So, again, the question: can we just access the font-weight and font-style information directly somehow? Or can we create a new string for which we are able to set this information? This would solve the problem of trying to switch from one font to another and preserving style info.

And a double clarification:

We are talking about iOS. When you set an attributed string's font attribute (NSFontAttributeName) for some range of characters, internally iOS creates an NSFont with a style string. The style string will read "font-weight: normal; font-style: normal" if you have set a font attribute yourself. But this style string is where the bold and italic information set in a UITextView (by toggling) is stored.

like image 357
Steve Cotner Avatar asked Nov 03 '12 20:11

Steve Cotner


People also ask

What is the difference between font style and font weight?

Font-weight is where you decide how thick the strokes of the letters are going to be. Font-style is where you decide whether the text is going to be italics, oblique (faux italics), or neither of these (i.e. roman or normal).

What is font weight used for?

Font weight is the “value” placed on your font that will determine how bold or light your text will appear.

What is the font weight by default?

So, when working with fonts : the default (aka "Regular") font weight is 400. the "bold" font weight is 700. the "light" font weight is 300.


1 Answers

Looks like you might be able to create a new CTFontRef using a CTFontAttributesRef where you have set value for attribute keys kCTFontWeightTrait and/or kCTFontSymbolicTrait. Does that help?

cf. CTFontDescriptorReference and CTFontReference

EDIT

Guess this won't work--I looked into it more myself... leaving this here in case someone else has the same idea.

like image 164
nielsbot Avatar answered Nov 12 '22 23:11

nielsbot