【问题标题】:NSAttributedString: Setting FontAttributes doesn't change fontNSAttributedString:设置 FontAttributes 不会改变字体
【发布时间】:2016-04-08 15:19:59
【问题描述】:

我正在尝试更改 NSAttributedString 上的字体。

我有一个方法可以遍历每个字符,并为该字符创建一个新的 NSFontAttribute 字典。然而,最后,字符串保持不变。为了演示,这是我设置字符串的方式:

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}];

这将为整个字符串生成以下 NSFontAttribute 字典:

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

我通过修改每个字符的FontAttribute添加粗体或斜体,如下:

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}];
}

这会产生许多不同的 FontAttributes:

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

但是,NSAttributedString 本身保持完全不变。它仍然是默认字体。我怎样才能让它反映我对其属性所做的更改?

【问题讨论】:

  • 仅供参考 - 阅读 UIFontSymbolicTrait 的文档。请注意,它需要 NSNumber 值,而不是 NSString
  • 此代码有效。文档不可靠。我尝试使用键“UIFontDescriptorTraitsAttribute”添加它,它确实需要一个 NSString,但它会引发异常:developer.apple.com/library/ios/documentation/UIKit/Reference/… 出于某种原因,这个“不正确”键是我可以将 traitsAttribute 添加到 FontAttributes 字典的唯一方法。不要问我为什么。
  • 但是您应该将值包装在 NSNumber 中,而不是 NSString。如[fontAttributes setValue:@([fontDescriptor symbolicTraits]) forKey:UIFontSymbolicTrait];
  • @maddy 你是对的。我对 UIFontDescriptorTraitsAttribute 感到困惑。我已经解决了这个问题,但它仍然对结果没有影响。

标签: ios objective-c nsstring nsattributedstring foundation


【解决方案1】:

解决方法如下:

1:UIFontDescriptor 的文档将密钥:UIFontDescriptorNameAttribute 定义为 NSString 实例,它就是这样。

2:NSAttributedString 的文档将密钥:NSFontAttributeName 定义为 UIFont 实例。

所以从使用(UIFontDescriptor *)fontDescriptorWithName:(NSString *)fontName size:(CGFloat)size 方法初始化的UIFontDescriptor 中获取fontAttributes 字典只会设置键UIFontDescriptorNameAttributeUIFontDescriptorSizeAttribute。但是,如果您希望实际修改 NSAttributedString 的字体,则需要应用保存到键 NSFontAttributeName 的 UIFont 实例的属性。

这就是混乱的来源。但是,需要注意的是,您实际上可以使用键 NSFontAttributeName 从 UIFontDescriptor 实例的 fontAttributes 字典中获取 UIFontDescriptorNameAttribute。这也可能令人困惑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多