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

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

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。斯威夫特在下标和上标上有什么招数?

6 个解决方案

#1


49  

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. 向要更改的字符(NSRange)添加一个属性,使用较小的/下标UIFont,而NSBaselineOffsetAttributeName值是您希望垂直抵消的量。
  7. Assign it to your UILabel
  8. 把它分配给你的UILabel

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

希望这能帮助其他的Swift devs,因为我也需要这个。

#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


5  

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上标和下标的数字:⁰¹²³⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉这个的优点是少了很多麻烦。

#4


4  

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中使用下标和上标

#5


2  

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}这样的结构。如果您想要将两者结合起来,还可以使用superandsubscript(字体:)。

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 UIKit

func 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)

#1


49  

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. 向要更改的字符(NSRange)添加一个属性,使用较小的/下标UIFont,而NSBaselineOffsetAttributeName值是您希望垂直抵消的量。
  7. Assign it to your UILabel
  8. 把它分配给你的UILabel

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

希望这能帮助其他的Swift devs,因为我也需要这个。

#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


5  

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上标和下标的数字:⁰¹²³⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉这个的优点是少了很多麻烦。

#4


4  

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中使用下标和上标

#5


2  

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}这样的结构。如果您想要将两者结合起来,还可以使用superandsubscript(字体:)。

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 UIKit

func 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)