Comment utiliser l'indice et le exposant dans Swift

je veux que mon UILabel pour afficher du texte dans la manière suivante 6.022*10 23. Quelles fumctions swift a-t-il pour l'indice et l'exposant?

23
demandé sur Adam Young 2015-03-24 08:43:19

8 réponses

la plupart des réponses+exemples sont dans ObjC, mais c'est la façon de le faire dans 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

Cela me donne:

SuperScript Example

Dans une explication plus détaillée:

  1. Get UIFont vous voulez à la fois le style par défaut et le style superscript, le superscript doit être plus petit.
  2. Créer un NSMutableAttributedString avec la chaîne complète et la police par défaut.
  3. Ajouter un attribut aux caractères que vous voulez changer (NSRange), avec les plus petits/indice UIFont et NSBaselineOffsetAttributeName la valeur est le montant que vous souhaitez décaler verticalement.
  4. Attribuer à votre UILabel

J'espère que cela aidera D'autres Devs Swift car j'en avais aussi besoin.

54
répondu Forrest Porter 2017-11-23 10:44:06

une approche différente, j'ai écrit une fonction qui prend une chaîne de caractères où les exposants sont précédées ^2^2•3•5^2 et renvoie 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
}

c'est un peu une méthode de force brute, mais cela fonctionne si vous ne voulez pas traiter les chaînes attribuées ou si vous voulez que votre chaîne soit indépendante d'une police.

10
répondu Chris 2015-12-18 21:03:44

j'ai écrit l'extension suivante, ou vous pouvez l'utiliser comme une fonction, il fonctionne bien pour moi . vous pouvez la modifier en sautant les parties qui ne sont pas essentielles pour vous

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}
  }

exemples:

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

enter image description here

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

enter image description here

9
répondu Atka 2017-03-03 23:38:23

si vous pouvez vous entendre avec un texte qui n'a pas l'air parfait, et n'a besoin que d'un sous-ensemble de caractères, vous pouvez utiliser les numéros unicode superscript et subscript: Cela a l'avantage d'être beaucoup moins lourd.

7
répondu Glenn Howes 2015-07-02 15:51:28

solution Swift simple à utiliser, vous pouvez checkout HandyUIKit. Après l'avoir importé dans votre projet (par exemple via Carthage-voir instructions dans README) vous pouvez faire quelque chose comme ceci:

import HandyUIKit

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

cette ligne renvoie un NSAttributedString qui ressemblera exactement à ce que vous cherchez. attribuerUILabels attributedText propriété et c'est c'!


si vous cherchez subscripting un texte, utilisez simplement subscripted(font:) à la place. Il reconnaîtra des structures comme CO_{2}. Il y a aussi superAndSubscripted(font:) si vous souhaitez combiner .

voir le docs pour plus d'informations et des exemples supplémentaires.

3
répondu Dschee 2017-09-28 12:44:27

Voici une version simple qui a une bonne gestion des erreurs et qui sera compilée dans 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)
0
répondu Randy Hill 2018-02-03 01:07:33

Swift 4+ Version de la réponse de @Atka

import UIKit

extension 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
    }
}
0
répondu Abhishek Thapliyal 2018-09-14 19:15:46

une jolie fonction simple qui affiche un nombre comme texte en exposant.

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
}
0
répondu gorillaz 2018-10-02 19:20:36