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:
这给了我:
In a more detailed explanation:
在更详细的解释中:
- Get
UIFont
you want for both the default and superscript style, superscript must be smaller. - Create a
NSMutableAttributedString
with the full string and default font. - Add an attribute to the characters you want to change (
NSRange
), with the smaller/subscriptUIFont
, and theNSBaselineOffsetAttributeName
value is the amount you want to offset it vertically. - Assign it to your
UILabel
获取UIFont你想要的默认和上标样式,上标必须更小。
使用完整字符串和默认字体创建NSMutableAttributedString。
使用较小的/下标UIFont向要更改的字符(NSRange)添加属性,NSBaselineOffsetAttributeName值是要垂直偏移的值。
将其分配给您的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)
let attStr2 = NSMutableAttributedString().characterSubscriptAndSuperscript( string: "H2SO4", characters: ["2","4"], type: .aSub, fontSize: 20, scriptFontSize: 15, offSet: 8, length: [1,1], alignment: .left)
#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 UILabel
s 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:
这给了我:
In a more detailed explanation:
在更详细的解释中:
- Get
UIFont
you want for both the default and superscript style, superscript must be smaller. - Create a
NSMutableAttributedString
with the full string and default font. - Add an attribute to the characters you want to change (
NSRange
), with the smaller/subscriptUIFont
, and theNSBaselineOffsetAttributeName
value is the amount you want to offset it vertically. - Assign it to your
UILabel
获取UIFont你想要的默认和上标样式,上标必须更小。
使用完整字符串和默认字体创建NSMutableAttributedString。
使用较小的/下标UIFont向要更改的字符(NSRange)添加属性,NSBaselineOffsetAttributeName值是要垂直偏移的值。
将其分配给您的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)
let attStr2 = NSMutableAttributedString().characterSubscriptAndSuperscript( string: "H2SO4", characters: ["2","4"], type: .aSub, fontSize: 20, scriptFontSize: 15, offSet: 8, length: [1,1], alignment: .left)
#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 UILabel
s 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}