NSAttributedString: Setting FontAttributes doesn't change font

ぃ、小莉子 提交于 2019-12-08 11:02:51

问题


I am trying to change the font on an NSAttributedString.

I have a method which iterates over each character, and creates a new NSFontAttribute dictionary for that character. In the end, however, the string remains un-changed. To demonstrate, here is how I setup the string:

UIFontDescriptor *fontDescriptor = [UIFontDescriptor fontDescriptorWithName:@"Avenir-Book" size:14.0f];

 NSDictionary *fontAttributes = [fontDescriptor fontAttributes];

 [fontAttributes setValue:[NSString stringWithFormat:@"%u",[fontDescriptor symbolicTraits]] forKey:UIFontSymbolicTrait];

 [mutableAttributedString setAttributes:fontAttributes range:(NSRange){0,length}];

This produces the following NSFontAttribute dictionary for the entire string:

Font Attributes: {
    NSCTFontSymbolicTrait = 2147483648;
    NSFontNameAttribute = "Avenir-Book";
    NSFontSizeAttribute = 14;
}

I go through and modify each character's FontAttribute to add bolding or italics, as follows:

for (int i = (int)range.location; i < (range.location + range.length); i++){
    /* Extract Font Attributes */
    NSDictionary *extractedAttributes = [[mutableAttributedString attributesAtIndex:i effectiveRange:NULL]mutableCopy];

    /* Determine New Trait */
    uint newTrait = ((uint)[[extractedAttributes valueForKey:UIFontSymbolicTrait]longLongValue] | [self symbolicTraitForMarkdownType:markdown]); // (markDown  is a mask)

    /* Set New Trait */
    [extractedAttributes setValue:[NSString stringWithFormat:@"%u",newTrait] forKey:UIFontSymbolicTrait];

    /* Create New Font Descriptor */
    UIFontDescriptor *newDescriptor = [UIFontDescriptor fontDescriptorWithFontAttributes:extractedAttributes];
    newDescriptor = [newDescriptor fontDescriptorWithSymbolicTraits:newTrait];

    /* Apply Font Descriptor */
    [mutableAttributedString setAttributes:[newDescriptor fontAttributes] range:(NSRange){i,1}];
}

This produces many different FontAttributes:

Index 1: {
    NSCTFontSymbolicTrait = 2147483650;
    NSFontNameAttribute = "Avenir-Black";
    NSFontSizeAttribute = 14;
}
Index 2: {
    NSCTFontSymbolicTrait = 2147483651;
    NSFontNameAttribute = "Avenir-BlackOblique";
    NSFontSizeAttribute = 14;
}

However, the NSAttributedString itself remains completely un-changed. It is still the default Font. How can I get it to reflect the changes I am making to its attributes?


回答1:


Here is the solution:

1: The documentation for UIFontDescriptor defines the key: UIFontDescriptorNameAttribute as an NSString instance, which it is.

2: The documentation for NSAttributedString defines the key: NSFontAttributeName as a UIFont instance.

So obtaining the fontAttributes dictionary from a UIFontDescriptor initialized with a the method: (UIFontDescriptor *)fontDescriptorWithName:(NSString *)fontName size:(CGFloat)size will only set the keys UIFontDescriptorNameAttribute and UIFontDescriptorSizeAttribute. If you wish to actually modify the font of an NSAttributedString however, you need to apply attributes with a UIFont instance saved to the key NSFontAttributeName.

This is where the confusion comes from. However, it should be noted that you can actually obtain UIFontDescriptorNameAttribute from the fontAttributes dictionary of a UIFontDescriptor instance with the key NSFontAttributeName. This may also be confusing.



来源:https://stackoverflow.com/questions/34600861/nsattributedstring-setting-fontattributes-doesnt-change-font

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!