如何使用NSAttributedString制作下标和上标?

26

我需要为化学式(H2O、Na^2+等)制作下标?

使用NSAttributedString是否可以实现这一功能,还是有其他/更简单的方法可以制作下标?

5个回答

34

以下是我在iOS 6中所做的。首先添加CoreText和QuartzCore框架。然后导入:

#import <QuartzCore/QuartzCore.h>
#import <CoreText/CTStringAttributes.h>
#import <CoreText/CoreText.h>

我写了一个小函数,它输入一个普通的NSString并导出一个带有上标的NSMutableAttributedString。可以修改此函数以允许设置上标或下标,将kCTSuperscriptAttributeName值更改为-1即可。此外,您可以添加一个变量来指定字符串中放置上标的位置。现在它只假定在字符串末尾。

- (NSMutableAttributedString *)plainStringToAttributedUnits:(NSString *)string;
{
    NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] initWithString:string];
    UIFont *font = [UIFont systemFontOfSize:10.0f];
    UIFont *smallFont = [UIFont systemFontOfSize:9.0f];

    [attString beginEditing];
    [attString addAttribute:NSFontAttributeName value:(font) range:NSMakeRange(0, string.length - 2)];
    [attString addAttribute:NSFontAttributeName value:(smallFont) range:NSMakeRange(string.length - 1, 1)];
    [attString addAttribute:(NSString*)kCTSuperscriptAttributeName value:@"1" range:NSMakeRange(string.length - 1, 1)];
    [attString addAttribute:(NSString*)kCTForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(0, string.length - 1)];
    [attString endEditing];
    return attString;
}

现在当我想要使用它时,我可以按照以下步骤将其放入UITextField中:

    NSString *qlwUnitsPlainText = @"m3";
    self.quantityLoadWeightUnits_textField.attributedText = [self plainStringToAttributedUnits:qlwUnitsPlainText];

我希望这对其他人有所帮助,因为这方面的示例不是很多!


你能否请看一下这个 attributedString 的部分:https://gist.github.com/mladjan/6663691 它不想渲染上标 :( - dormitkon
3
注意,NSMakeRange的参数是firstPosition和length(而不是firstPosition和lastPosition)。在示例中,读者可能会被误导。 - dwbrito
如何删除它。 - H Raval

28
这可以通过使用NSAttributedString实现。您要查找的属性常量取决于您的平台。对于Mac OS X,它是NSSuperscriptAttributeName,对于iOS,它是kCTSuperscriptAttributeName。对于下标,请传递一个负值。
唯一的注意点是,iOS上的UILabel不能绘制NSAttributedString(但希望在iOS 6中能够实现)。您需要使用核心文本绘制文本,或查找一些第三方替代UILabel,该替代品可以绘制NSAttributedString

谢谢。您能否使用kCTSuperscriptAttributeName来制作上标? - Mahir
1
是的,正值表示上标。负值表示下标。 - Mark Adams
抱歉,我不知道我怎么会错过那个。再次感谢。 - Mahir
需要注意的是,UILabel现在通过attributedString属性支持NSAttributedStringkCTSuperscriptAttributeName的值也可以是介于-1和1之间的小数值,以改变上标/下标文本的位置,以适应您的需求。 - Bensge

9
在iOS上,我错过了kCTSuperscriptAttributeName常量,但是通过字体大小和“基线”取得了不错的效果。这也为不那么顺从的字体提供了更多的控制:
+ (NSAttributedString *)attributedStringForText:(NSString *)normalText andSuperscript:(NSString *)superscriptText textSize:(CGFloat)textSize
{
    UIFont *normalFont = [Styles mainFontWithSize:textSize];
    UIFont *superFont = [Styles mainFontWithSize:textSize / 2];

    NSMutableAttributedString *finalStr = [[NSMutableAttributedString alloc] initWithString:normalText attributes:@{NSFontAttributeName: normalFont}];

    NSAttributedString *superStr = [[NSAttributedString alloc] initWithString:superscriptText attributes:@{NSFontAttributeName: superFont, NSBaselineOffsetAttributeName:@(textSize/2)}];

    [finalStr appendAttributedString:superStr];

    return finalStr;
}       

1
这里的 Styles 是什么? - Aadil Keshwani
@AadilKeshwani 这只是一个静态类,用于集中应用程序相关的字体、大小、颜色和其他样式。 - Hari Honor
@AadilKeshwani Styles只是一个静态类,作为样式表,将应用程序中大部分样式常量集中在一起。 - Hari Honor

1
对于SubScript,请将kCTSuperscriptAttributeName的值设置为@-1。
根据文档,
讨论:值必须是CFNumberRef。默认值为int值0。如果指定的字体支持,则值为1启用上标,值为-1启用下标。
extern const CFStringRef kCTSuperscriptAttributeName CT_AVAILABLE(10_5, 3_2);
 Example- [lblHeader setText:@“Headers [Alpha1 – text”];

        NSMutableAttributedString *headerSubscript = [[NSMutableAttributedString alloc]initWithAttributedString: lblHeader.attributedText];

        [headerSubscript addAttribute:(NSString *)kCTSuperscriptAttributeName value:@-1 range:NSMakeRange(14,1)];      

        [lblHeader setAttributedText:headerSubscript];

@Bhargav Rao 这是用 Swift 编写的,这就是我写这个答案的原因。 - Dharmbir Singh

0

如果你想让它更整洁一些,可以尝试以下方法

NSDictionary *attr = @{ NSFontAttributeName: smallfont, 
                        (NSString*)kCTSuperscriptAttributeName: @1 }

NSRange fabricWeightRange = NSMakeRange(fabricWeight.location + 2, 1);                   
[subKeyString setAttributes:attr range:fabricWeightRange];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接