如何在Swift中使用下标和上标

时间:2021-08-01 20:11:28

I want my UILabel to display text in following manner 6.022*1023. What fumctions does swift have for subscript and superscript?

我希望我的UILabel以下列方式显示文本6.022 * 1023。迅速对下标和上标有什么影响?

8 个解决方案

#1


55  

Most of the answers+examples are in ObjC, but this is how to do it in Swift.

大多数答案+示例都在ObjC中,但这是如何在Swift中完成的。

let font:UIFont? = UIFont(name: "Helvetica", size:20)let fontSuper:UIFont? = UIFont(name: "Helvetica", size:10)let attString:NSMutableAttributedString = NSMutableAttributedString(string: "6.022*1023", attributes: [.font:font!])attString.setAttributes([.font:fontSuper!,.baselineOffset:10], range: NSRange(location:8,length:2))labelVarName.attributedText = attString

This gives me:

这给了我:

如何在Swift中使用下标和上标

In a more detailed explanation:

在更详细的解释中:

  1. Get UIFont you want for both the default and superscript style, superscript must be smaller.
  2. 获取UIFont你想要的默认和上标样式,上标必须更小。

  3. Create a NSMutableAttributedString with the full string and default font.
  4. 使用完整字符串和默认字体创建NSMutableAttributedString。

  5. Add an attribute to the characters you want to change (NSRange), with the smaller/subscript UIFont, and the NSBaselineOffsetAttributeName value is the amount you want to offset it vertically.
  6. 使用较小的/下标UIFont向要更改的字符(NSRange)添加属性,NSBaselineOffsetAttributeName值是要垂直偏移的值。

  7. Assign it to your UILabel
  8. 将其分配给您的UILabel

Hopefully this helps other Swift devs as I needed this as well.

希望这也有助于其他Swift开发者,因为我也需要它。

#2


10  

As a different approach, I wrote a function that takes in a string where the exponents are prepended with ^ such as 2^2•3•5^2 and returns 2²•3•5²

作为一种不同的方法,我编写了一个函数,它接受一个字符串,其中指数前缀为^,例如2 ^ 2•3•5 ^ 2并返回2²•3•5²

func exponentize(str: String) -> String {    let supers = [        "1": "\u{00B9}",        "2": "\u{00B2}",        "3": "\u{00B3}",        "4": "\u{2074}",        "5": "\u{2075}",        "6": "\u{2076}",        "7": "\u{2077}",        "8": "\u{2078}",        "9": "\u{2079}"]    var newStr = ""    var isExp = false    for (_, char) in str.characters.enumerate() {        if char == "^" {            isExp = true        } else {            if isExp {                let key = String(char)                if supers.keys.contains(key) {                    newStr.append(Character(supers[key]!))                } else {                    isExp = false                    newStr.append(char)                }            } else {                newStr.append(char)            }        }    }    return newStr}

It's a bit of a brute force method, but it works if you don't want to deal with attributed strings or you want your string to be independent of a font.

这是一种蛮力方法,但如果您不想处理属性字符串或希望字符串独立于字体,则它可以工作。

#3


9  

I wrote the following extension or you can use it as a function, it is working well for me . you can modify it by skipping the parts that are not essential to you

我编写了以下扩展名,或者您可以将其用作函数,它对我来说效果很好。您可以通过跳过对您来说不重要的部分来修改它

extension NSMutableAttributedString{enum scripting : Int{    case aSub = -1    case aSuper = 1}func characterSubscriptAndSuperscript(string:String,                                      characters:[Character],                                      type:scripting,                                      fontSize:CGFloat,                                      scriptFontSize:CGFloat,                                      offSet:Int,                                      length:[Int],                                      alignment:NSTextAlignment)-> NSMutableAttributedString{    let paraghraphStyle = NSMutableParagraphStyle()     // Set The Paragraph aligmnet , you can ignore this part and delet off the function    paraghraphStyle.alignment = alignment    var scriptedCharaterLocation = Int()    //Define the fonts you want to use and sizes    let stringFont = UIFont.boldSystemFont(ofSize: fontSize)    let scriptFont = UIFont.boldSystemFont(ofSize: scriptFontSize)     // Define Attributes of the text body , this part can be removed of the function    let attString = NSMutableAttributedString(string:string, attributes: [NSFontAttributeName:stringFont,NSForegroundColorAttributeName:UIColor.black,NSParagraphStyleAttributeName: paraghraphStyle])    // the enum is used here declaring the required offset    let baseLineOffset = offSet * type.rawValue    // enumerated the main text characters using a for loop    for (i,c) in string.characters.enumerated()    {        // enumerated the array of first characters to subscript        for (theLength,aCharacter) in characters.enumerated()        {            if c == aCharacter            {               // Get to location of the first character                scriptedCharaterLocation = i              //Now set attributes starting from the character above                    attString.setAttributes([NSFontAttributeName:scriptFont,              // baseline off set from . the enum i.e. +/- 1                        NSBaselineOffsetAttributeName:baseLineOffset,              NSForegroundColorAttributeName:UIColor.black],               // the range from above location         range:NSRange(location:scriptedCharaterLocation,         // you define the length in the length array          // if subscripting at different location          // you need to define the length for each one         length:length[theLength]))            }        }    }    return attString}  }

examples:

let attStr1 = NSMutableAttributedString().characterSubscriptAndSuperscript(               string: "23 x 456",                characters:["3","5"],                type: .aSuper,                fontSize: 20,                scriptFontSize: 15,                offSet: 10,                length: [1,2],                alignment: .left)

如何在Swift中使用下标和上标

let attStr2 = NSMutableAttributedString().characterSubscriptAndSuperscript(           string: "H2SO4",            characters: ["2","4"],            type: .aSub,            fontSize: 20,            scriptFontSize: 15,             offSet: 8,            length: [1,1],            alignment: .left)

如何在Swift中使用下标和上标

#4


7  

If you can get along with text that doesn't look perfect, and only need a subset of characters you can make use of the unicode superscript and subscript numbers: ⁰ ¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹ ₀ ₁ ₂ ₃ ₄ ₅ ₆ ₇ ₈ ₉ This has the advantage of being a lot less cumbersome.

如果你可以使用看起来不完美的文本,并且只需要一个字符子集就可以使用unicode上标和下标数字:⁰¹³⁴⁵⁶⁷⁸⁹₂₂₂₃₄₄₅₅₅₅₅₅₅₅₅⁹⁹₂₂₂₂₄₅₅₅₅₅⁹⁹⁹₂ ₇₇₈这样做的好处是不那么麻烦。

#5


3  

For a simple to use Swift solution, you might want to checkout HandyUIKit. After importing it into your project (e.g. via Carthage – see instructions in README) you can do something like this:

对于简单易用的Swift解决方案,您可能需要签出HandyUIKit。将其导入项目后(例如通过Carthage - 参见README中的说明),您可以执行以下操作:

import HandyUIKit"6.022*10^{23}".superscripted(font: UIFont.systemFont(ofSize: 20, weight: .medium))

This line will return an NSAttributedString which will look exactly like what you're looking for. Just assign it to a UILabels attributedText property and that's it!

这一行将返回一个NSAttributedString,它看起来与你正在寻找的完全一样。只需将其分配给UILabels attributedText属性就可以了!


If you're looking for subscripting a text, simply use subscripted(font:) instead. It will recognize structures like CO_{2}. There's also superAndSubscripted(font:) if you want to combine both.

如果您正在寻找订阅文本,请使用下标(字体:)代替。它将识别CO_ {2}之类的结构。如果你想将两者结合起来,还有superAndSubscripted(font :)。

See the docs for more information and additional examples.

有关更多信息和其他示例,请参阅文档。

#6


0  

Here is a simple version that has correct error handling and will compile in playground.

这是一个简单的版本,具有正确的错误处理,将在操场上编译。

import UIKitfunc setMyLabelText(myLabel: UILabel) {    if let largeFont = UIFont(name: "Helvetica", size: 20), let superScriptFont = UIFont(name: "Helvetica", size:10) {        let numberString = NSMutableAttributedString(string: "6.022*10", attributes: [.font: largeFont])        numberString.append(NSAttributedString(string: "23", attributes: [.font: superScriptFont, .baselineOffset: 10]))        myLabel.attributedText = numberString    }}let myLabel = UILabel()setMyLabelText(myLabel: myLabel)

#7


0  

Swift 4+ Version of @Atka's Answer

import UIKitextension NSMutableAttributedString {    enum Scripting : Int {        case aSub = -1        case aSuper = 1    }    func scripts(string: String,                  characters: [Character],                  type: Scripting,                  stringFont: UIFont,                  fontSize: CGFloat,                  scriptFont: UIFont,                  scriptFontSize: CGFloat,                  offSet: Int,                  length: [Int],                  alignment: NSTextAlignment) -> NSMutableAttributedString {        let paraghraphStyle = NSMutableParagraphStyle()        paraghraphStyle.alignment = alignment        var scriptedCharaterLocation = Int()        let attributes = [              NSAttributedStringKey.font: stringFont,              NSAttributedStringKey.foregroundColor: UIColor.black,              NSAttributedStringKey.paragraphStyle: paraghraphStyle        ]        let attString = NSMutableAttributedString(string:string, attributes: attributes)        let baseLineOffset = offSet * type.rawValue        let scriptTextAttributes: [NSAttributedStringKey : Any] = [            NSAttributedStringKey.font: scriptFont,            NSAttributedStringKey.baselineOffset: baseLineOffset,            NSAttributedStringKey.foregroundColor: UIColor.blue        ]        for (i,c) in string.enumerated() {            for (theLength, aCharacter) in characters.enumerated() {                if c == aCharacter {                    scriptedCharaterLocation = i                    attString.setAttributes(scriptTextAttributes, range: NSRange(location:scriptedCharaterLocation,                                                                                 length: length[theLength]))                }            }        }        return attString    }}

#8


0  

A nice simple function that outputs a number as the superscript text.

一个很好的简单函数,输出一个数字作为上标文本。

func exponent(i: Int) -> String {    let powers : [String] = [      "\u{2070}",      "\u{00B9}",      "\u{00B2}",      "\u{00B3}",      "\u{2074}",      "\u{2075}",      "\u{2076}",      "\u{2077}",      "\u{2078}",      "\u{2079}"    ]    let digits = Array(String(i))    var string = ""    for d in digits {      string.append("\(powers[Int(String(d))!])")    }    return string}

#1


55  

Most of the answers+examples are in ObjC, but this is how to do it in Swift.

大多数答案+示例都在ObjC中,但这是如何在Swift中完成的。

let font:UIFont? = UIFont(name: "Helvetica", size:20)let fontSuper:UIFont? = UIFont(name: "Helvetica", size:10)let attString:NSMutableAttributedString = NSMutableAttributedString(string: "6.022*1023", attributes: [.font:font!])attString.setAttributes([.font:fontSuper!,.baselineOffset:10], range: NSRange(location:8,length:2))labelVarName.attributedText = attString

This gives me:

这给了我:

如何在Swift中使用下标和上标

In a more detailed explanation:

在更详细的解释中:

  1. Get UIFont you want for both the default and superscript style, superscript must be smaller.
  2. 获取UIFont你想要的默认和上标样式,上标必须更小。

  3. Create a NSMutableAttributedString with the full string and default font.
  4. 使用完整字符串和默认字体创建NSMutableAttributedString。

  5. Add an attribute to the characters you want to change (NSRange), with the smaller/subscript UIFont, and the NSBaselineOffsetAttributeName value is the amount you want to offset it vertically.
  6. 使用较小的/下标UIFont向要更改的字符(NSRange)添加属性,NSBaselineOffsetAttributeName值是要垂直偏移的值。

  7. Assign it to your UILabel
  8. 将其分配给您的UILabel

Hopefully this helps other Swift devs as I needed this as well.

希望这也有助于其他Swift开发者,因为我也需要它。

#2


10  

As a different approach, I wrote a function that takes in a string where the exponents are prepended with ^ such as 2^2•3•5^2 and returns 2²•3•5²

作为一种不同的方法,我编写了一个函数,它接受一个字符串,其中指数前缀为^,例如2 ^ 2•3•5 ^ 2并返回2²•3•5²

func exponentize(str: String) -> String {    let supers = [        "1": "\u{00B9}",        "2": "\u{00B2}",        "3": "\u{00B3}",        "4": "\u{2074}",        "5": "\u{2075}",        "6": "\u{2076}",        "7": "\u{2077}",        "8": "\u{2078}",        "9": "\u{2079}"]    var newStr = ""    var isExp = false    for (_, char) in str.characters.enumerate() {        if char == "^" {            isExp = true        } else {            if isExp {                let key = String(char)                if supers.keys.contains(key) {                    newStr.append(Character(supers[key]!))                } else {                    isExp = false                    newStr.append(char)                }            } else {                newStr.append(char)            }        }    }    return newStr}

It's a bit of a brute force method, but it works if you don't want to deal with attributed strings or you want your string to be independent of a font.

这是一种蛮力方法,但如果您不想处理属性字符串或希望字符串独立于字体,则它可以工作。

#3


9  

I wrote the following extension or you can use it as a function, it is working well for me . you can modify it by skipping the parts that are not essential to you

我编写了以下扩展名,或者您可以将其用作函数,它对我来说效果很好。您可以通过跳过对您来说不重要的部分来修改它

extension NSMutableAttributedString{enum scripting : Int{    case aSub = -1    case aSuper = 1}func characterSubscriptAndSuperscript(string:String,                                      characters:[Character],                                      type:scripting,                                      fontSize:CGFloat,                                      scriptFontSize:CGFloat,                                      offSet:Int,                                      length:[Int],                                      alignment:NSTextAlignment)-> NSMutableAttributedString{    let paraghraphStyle = NSMutableParagraphStyle()     // Set The Paragraph aligmnet , you can ignore this part and delet off the function    paraghraphStyle.alignment = alignment    var scriptedCharaterLocation = Int()    //Define the fonts you want to use and sizes    let stringFont = UIFont.boldSystemFont(ofSize: fontSize)    let scriptFont = UIFont.boldSystemFont(ofSize: scriptFontSize)     // Define Attributes of the text body , this part can be removed of the function    let attString = NSMutableAttributedString(string:string, attributes: [NSFontAttributeName:stringFont,NSForegroundColorAttributeName:UIColor.black,NSParagraphStyleAttributeName: paraghraphStyle])    // the enum is used here declaring the required offset    let baseLineOffset = offSet * type.rawValue    // enumerated the main text characters using a for loop    for (i,c) in string.characters.enumerated()    {        // enumerated the array of first characters to subscript        for (theLength,aCharacter) in characters.enumerated()        {            if c == aCharacter            {               // Get to location of the first character                scriptedCharaterLocation = i              //Now set attributes starting from the character above                    attString.setAttributes([NSFontAttributeName:scriptFont,              // baseline off set from . the enum i.e. +/- 1                        NSBaselineOffsetAttributeName:baseLineOffset,              NSForegroundColorAttributeName:UIColor.black],               // the range from above location         range:NSRange(location:scriptedCharaterLocation,         // you define the length in the length array          // if subscripting at different location          // you need to define the length for each one         length:length[theLength]))            }        }    }    return attString}  }

examples:

let attStr1 = NSMutableAttributedString().characterSubscriptAndSuperscript(               string: "23 x 456",                characters:["3","5"],                type: .aSuper,                fontSize: 20,                scriptFontSize: 15,                offSet: 10,                length: [1,2],                alignment: .left)

如何在Swift中使用下标和上标

let attStr2 = NSMutableAttributedString().characterSubscriptAndSuperscript(           string: "H2SO4",            characters: ["2","4"],            type: .aSub,            fontSize: 20,            scriptFontSize: 15,             offSet: 8,            length: [1,1],            alignment: .left)

如何在Swift中使用下标和上标

#4


7  

If you can get along with text that doesn't look perfect, and only need a subset of characters you can make use of the unicode superscript and subscript numbers: ⁰ ¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹ ₀ ₁ ₂ ₃ ₄ ₅ ₆ ₇ ₈ ₉ This has the advantage of being a lot less cumbersome.

如果你可以使用看起来不完美的文本,并且只需要一个字符子集就可以使用unicode上标和下标数字:⁰¹³⁴⁵⁶⁷⁸⁹₂₂₂₃₄₄₅₅₅₅₅₅₅₅₅⁹⁹₂₂₂₂₄₅₅₅₅₅⁹⁹⁹₂ ₇₇₈这样做的好处是不那么麻烦。

#5


3  

For a simple to use Swift solution, you might want to checkout HandyUIKit. After importing it into your project (e.g. via Carthage – see instructions in README) you can do something like this:

对于简单易用的Swift解决方案,您可能需要签出HandyUIKit。将其导入项目后(例如通过Carthage - 参见README中的说明),您可以执行以下操作:

import HandyUIKit"6.022*10^{23}".superscripted(font: UIFont.systemFont(ofSize: 20, weight: .medium))

This line will return an NSAttributedString which will look exactly like what you're looking for. Just assign it to a UILabels attributedText property and that's it!

这一行将返回一个NSAttributedString,它看起来与你正在寻找的完全一样。只需将其分配给UILabels attributedText属性就可以了!


If you're looking for subscripting a text, simply use subscripted(font:) instead. It will recognize structures like CO_{2}. There's also superAndSubscripted(font:) if you want to combine both.

如果您正在寻找订阅文本,请使用下标(字体:)代替。它将识别CO_ {2}之类的结构。如果你想将两者结合起来,还有superAndSubscripted(font :)。

See the docs for more information and additional examples.

有关更多信息和其他示例,请参阅文档。

#6


0  

Here is a simple version that has correct error handling and will compile in playground.

这是一个简单的版本,具有正确的错误处理,将在操场上编译。

import UIKitfunc setMyLabelText(myLabel: UILabel) {    if let largeFont = UIFont(name: "Helvetica", size: 20), let superScriptFont = UIFont(name: "Helvetica", size:10) {        let numberString = NSMutableAttributedString(string: "6.022*10", attributes: [.font: largeFont])        numberString.append(NSAttributedString(string: "23", attributes: [.font: superScriptFont, .baselineOffset: 10]))        myLabel.attributedText = numberString    }}let myLabel = UILabel()setMyLabelText(myLabel: myLabel)

#7


0  

Swift 4+ Version of @Atka's Answer

import UIKitextension NSMutableAttributedString {    enum Scripting : Int {        case aSub = -1        case aSuper = 1    }    func scripts(string: String,                  characters: [Character],                  type: Scripting,                  stringFont: UIFont,                  fontSize: CGFloat,                  scriptFont: UIFont,                  scriptFontSize: CGFloat,                  offSet: Int,                  length: [Int],                  alignment: NSTextAlignment) -> NSMutableAttributedString {        let paraghraphStyle = NSMutableParagraphStyle()        paraghraphStyle.alignment = alignment        var scriptedCharaterLocation = Int()        let attributes = [              NSAttributedStringKey.font: stringFont,              NSAttributedStringKey.foregroundColor: UIColor.black,              NSAttributedStringKey.paragraphStyle: paraghraphStyle        ]        let attString = NSMutableAttributedString(string:string, attributes: attributes)        let baseLineOffset = offSet * type.rawValue        let scriptTextAttributes: [NSAttributedStringKey : Any] = [            NSAttributedStringKey.font: scriptFont,            NSAttributedStringKey.baselineOffset: baseLineOffset,            NSAttributedStringKey.foregroundColor: UIColor.blue        ]        for (i,c) in string.enumerated() {            for (theLength, aCharacter) in characters.enumerated() {                if c == aCharacter {                    scriptedCharaterLocation = i                    attString.setAttributes(scriptTextAttributes, range: NSRange(location:scriptedCharaterLocation,                                                                                 length: length[theLength]))                }            }        }        return attString    }}

#8


0  

A nice simple function that outputs a number as the superscript text.

一个很好的简单函数,输出一个数字作为上标文本。

func exponent(i: Int) -> String {    let powers : [String] = [      "\u{2070}",      "\u{00B9}",      "\u{00B2}",      "\u{00B3}",      "\u{2074}",      "\u{2075}",      "\u{2076}",      "\u{2077}",      "\u{2078}",      "\u{2079}"    ]    let digits = Array(String(i))    var string = ""    for d in digits {      string.append("\(powers[Int(String(d))!])")    }    return string}