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:
这给我:
In a more detailed explanation:
在更详细的解释中:
- Get
UIFont
you want for both the default and superscript style, superscript must be smaller. - 获得你想要的UIFont为默认和上标样式,上标必须是小的。
- Create a
NSMutableAttributedString
with the full string and default font. - 创建一个带有完整字符串和默认字体的NSMutableAttributedString。
- 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. - 向要更改的字符(NSRange)添加一个属性,使用较小的/下标UIFont,而NSBaselineOffsetAttributeName值是您希望垂直抵消的量。
- Assign it to your
UILabel
- 把它分配给你的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)
let attStr2 = NSMutableAttributedString().characterSubscriptAndSuperscript(
string: "H2SO4",
characters: ["2","4"],
type: .aSub,
fontSize: 20,
scriptFontSize: 15,
offSet: 8,
length: [1,1],
alignment: .left)
#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 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}这样的结构。如果您想要将两者结合起来,还可以使用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:
这给我:
In a more detailed explanation:
在更详细的解释中:
- Get
UIFont
you want for both the default and superscript style, superscript must be smaller. - 获得你想要的UIFont为默认和上标样式,上标必须是小的。
- Create a
NSMutableAttributedString
with the full string and default font. - 创建一个带有完整字符串和默认字体的NSMutableAttributedString。
- 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. - 向要更改的字符(NSRange)添加一个属性,使用较小的/下标UIFont,而NSBaselineOffsetAttributeName值是您希望垂直抵消的量。
- Assign it to your
UILabel
- 把它分配给你的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)
let attStr2 = NSMutableAttributedString().characterSubscriptAndSuperscript(
string: "H2SO4",
characters: ["2","4"],
type: .aSub,
fontSize: 20,
scriptFontSize: 15,
offSet: 8,
length: [1,1],
alignment: .left)
#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 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}这样的结构。如果您想要将两者结合起来,还可以使用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)