Wie erstelle ich mit Swift eine zugeordnete Zeichenfolge?

316

Ich versuche einen einfachen Kaffeerechner zu machen. Ich muss die Kaffeemenge in Gramm anzeigen. Das "g" -Symbol für Gramm muss an mein UILabel angehängt werden, mit dem ich den Betrag anzeige. Die Zahlen im UILabel ändern sich dynamisch mit Benutzereingaben, aber ich muss am Ende der Zeichenfolge ein Kleinbuchstaben "g" hinzufügen, das anders formatiert ist als die aktualisierten Zahlen. Das "g" muss an die Zahlen angehängt werden, damit sich das "g" mit den Zahlen bewegt, wenn sich die Größe und Position der Zahl ändert. Ich bin mir sicher, dass dieses Problem schon einmal gelöst wurde, daher wäre ein Link in die richtige Richtung hilfreich, da ich mein kleines Herz gegoogelt habe.

Ich habe die Dokumentation nach einer zugeordneten Zeichenfolge durchsucht und sogar einen "Attributed String Creator" aus dem App Store heruntergeladen, aber der resultierende Code befindet sich in Objective-C und ich verwende Swift. Was großartig und wahrscheinlich hilfreich für andere Entwickler wäre, die diese Sprache lernen, ist ein klares Beispiel für das Erstellen einer benutzerdefinierten Schriftart mit benutzerdefinierten Attributen unter Verwendung einer zugewiesenen Zeichenfolge in Swift. Die Dokumentation hierfür ist sehr verwirrend, da es keinen sehr klaren Weg gibt, wie dies zu tun ist. Mein Plan ist es, die zugewiesene Zeichenfolge zu erstellen und am Ende meiner KaffeeAmount-Zeichenfolge hinzuzufügen.

var coffeeAmount: String = calculatedCoffee + attributedText

Wobei berechneCoffee ein Int ist, das in eine Zeichenfolge konvertiert wurde, und "attributedText" das Kleinbuchstaben "g" mit der benutzerdefinierten Schriftart ist, die ich erstellen möchte. Vielleicht gehe ich das falsch an. Jede Hilfe wird geschätzt!

dcbenji
quelle

Antworten:

968

Geben Sie hier die Bildbeschreibung ein

Diese Antwort wurde für Swift 4.2 aktualisiert.

Kurzübersicht

Die allgemeine Form zum Erstellen und Festlegen einer zugewiesenen Zeichenfolge lautet wie folgt. Weitere gängige Optionen finden Sie unten.

// create attributed string
let myString = "Swift Attributed String"
let myAttribute = [ NSAttributedString.Key.foregroundColor: UIColor.blue ]
let myAttrString = NSAttributedString(string: myString, attributes: myAttribute) 

// set attributed text on a UILabel
myLabel.attributedText = myAttrString

Textfarbe

let myAttribute = [ NSAttributedString.Key.foregroundColor: UIColor.blue ]

Hintergrundfarbe

let myAttribute = [ NSAttributedString.Key.backgroundColor: UIColor.yellow ]

Schriftart

let myAttribute = [ NSAttributedString.Key.font: UIFont(name: "Chalkduster", size: 18.0)! ]

Geben Sie hier die Bildbeschreibung ein

let myAttribute = [ NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue ]

Geben Sie hier die Bildbeschreibung ein

let myShadow = NSShadow()
myShadow.shadowBlurRadius = 3
myShadow.shadowOffset = CGSize(width: 3, height: 3)
myShadow.shadowColor = UIColor.gray

let myAttribute = [ NSAttributedString.Key.shadow: myShadow ]

Der Rest dieses Beitrags enthält weitere Details für Interessierte.


Attribute

Zeichenfolgenattribute sind nur ein Wörterbuch in Form von [NSAttributedString.Key: Any], wobei NSAttributedString.Keyder Schlüsselname des Attributs und Anyder Wert eines Typs ist. Der Wert kann eine Schriftart, eine Farbe, eine Ganzzahl oder etwas anderes sein. Es gibt viele Standardattribute in Swift, die bereits vordefiniert wurden. Zum Beispiel:

  • Schlüsselname : NSAttributedString.Key.font, Wert: aUIFont
  • Schlüsselname : NSAttributedString.Key.foregroundColor, Wert: aUIColor
  • Schlüsselname : NSAttributedString.Key.link, Wert: ein NSURLoderNSString

Es gibt viele andere. Siehe diesen Link für mehr. Sie können sogar Ihre eigenen benutzerdefinierten Attribute erstellen wie:

  • Schlüsselname : NSAttributedString.Key.myName, Wert: einige Typ.
    Wenn Sie eine Erweiterung vornehmen :

    extension NSAttributedString.Key {
        static let myName = NSAttributedString.Key(rawValue: "myCustomAttributeKey")
    }

Attribute in Swift erstellen

Sie können Attribute wie jedes andere Wörterbuch deklarieren.

// single attributes declared one at a time
let singleAttribute1 = [ NSAttributedString.Key.foregroundColor: UIColor.green ]
let singleAttribute2 = [ NSAttributedString.Key.backgroundColor: UIColor.yellow ]
let singleAttribute3 = [ NSAttributedString.Key.underlineStyle: NSUnderlineStyle.double.rawValue ]

// multiple attributes declared at once
let multipleAttributes: [NSAttributedString.Key : Any] = [
    NSAttributedString.Key.foregroundColor: UIColor.green,
    NSAttributedString.Key.backgroundColor: UIColor.yellow,
    NSAttributedString.Key.underlineStyle: NSUnderlineStyle.double.rawValue ]

// custom attribute
let customAttribute = [ NSAttributedString.Key.myName: "Some value" ]

Beachten Sie das rawValue, was für den Unterstreichungsstilwert benötigt wurde.

Da Attribute nur Wörterbücher sind, können Sie sie auch erstellen, indem Sie ein leeres Wörterbuch erstellen und dann Schlüssel-Wert-Paare hinzufügen. Wenn der Wert mehrere Typen enthält, müssen Sie ihn Anyals Typ verwenden. Hier ist das multipleAttributesBeispiel von oben, das auf diese Weise neu erstellt wurde:

var multipleAttributes = [NSAttributedString.Key : Any]()
multipleAttributes[NSAttributedString.Key.foregroundColor] = UIColor.green
multipleAttributes[NSAttributedString.Key.backgroundColor] = UIColor.yellow
multipleAttributes[NSAttributedString.Key.underlineStyle] = NSUnderlineStyle.double.rawValue

Zugeschriebene Zeichenfolgen

Nachdem Sie die Attribute verstanden haben, können Sie zugeordnete Zeichenfolgen erstellen.

Initialisierung

Es gibt verschiedene Möglichkeiten, zugeordnete Zeichenfolgen zu erstellen. Wenn Sie nur eine schreibgeschützte Zeichenfolge benötigen, können Sie diese verwenden NSAttributedString. Hier sind einige Möglichkeiten, um es zu initialisieren:

// Initialize with a string only
let attrString1 = NSAttributedString(string: "Hello.")

// Initialize with a string and inline attribute(s)
let attrString2 = NSAttributedString(string: "Hello.", attributes: [NSAttributedString.Key.myName: "A value"])

// Initialize with a string and separately declared attribute(s)
let myAttributes1 = [ NSAttributedString.Key.foregroundColor: UIColor.green ]
let attrString3 = NSAttributedString(string: "Hello.", attributes: myAttributes1)

Wenn Sie die Attribute oder den Zeichenfolgeninhalt später ändern müssen, sollten Sie verwenden NSMutableAttributedString. Die Erklärungen sind sehr ähnlich:

// Create a blank attributed string
let mutableAttrString1 = NSMutableAttributedString()

// Initialize with a string only
let mutableAttrString2 = NSMutableAttributedString(string: "Hello.")

// Initialize with a string and inline attribute(s)
let mutableAttrString3 = NSMutableAttributedString(string: "Hello.", attributes: [NSAttributedString.Key.myName: "A value"])

// Initialize with a string and separately declared attribute(s)
let myAttributes2 = [ NSAttributedString.Key.foregroundColor: UIColor.green ]
let mutableAttrString4 = NSMutableAttributedString(string: "Hello.", attributes: myAttributes2)

Ändern einer zugeordneten Zeichenfolge

Als Beispiel erstellen wir die zugewiesene Zeichenfolge oben in diesem Beitrag.

Erstellen Sie zunächst ein NSMutableAttributedStringmit einem neuen Schriftattribut.

let myAttribute = [ NSAttributedString.Key.font: UIFont(name: "Chalkduster", size: 18.0)! ]
let myString = NSMutableAttributedString(string: "Swift", attributes: myAttribute )

Wenn Sie mitarbeiten, setzen Sie die zugewiesene Zeichenfolge wie folgt auf UITextView(oder UILabel):

textView.attributedText = myString

Sie nicht verwenden textView.text.

Hier ist das Ergebnis:

Geben Sie hier die Bildbeschreibung ein

Fügen Sie dann eine weitere zugeordnete Zeichenfolge hinzu, für die keine Attribute festgelegt sind. (Beachten Sie, dass ich es let, obwohl ich es myStringoben deklariert habe , trotzdem ändern kann, weil es ein ist NSMutableAttributedString. Dies scheint mir ziemlich unkompliziert zu sein, und ich wäre nicht überrascht, wenn sich dies in Zukunft ändert. Hinterlassen Sie mir in diesem Fall einen Kommentar.)

let attrString = NSAttributedString(string: " Attributed Strings")
myString.append(attrString)

Geben Sie hier die Bildbeschreibung ein

Als nächstes wählen wir einfach das Wort "Strings" aus, das am Index beginnt 17und eine Länge von hat 7. Beachten Sie, dass dies ein NSRangeund kein Swift ist Range. (Weitere Informationen zu Bereichen finden Sie in dieser Antwort .) Mit dieser addAttributeMethode können wir den Attributschlüsselnamen an die erste Stelle, den Attributwert an die zweite Stelle und den Bereich an die dritte Stelle setzen.

var myRange = NSRange(location: 17, length: 7) // range starting at location 17 with a lenth of 7: "Strings"
myString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.red, range: myRange)

Geben Sie hier die Bildbeschreibung ein

Zuletzt fügen wir eine Hintergrundfarbe hinzu. Verwenden Sie für Abwechslung die addAttributesMethode (beachten Sie die s). Ich könnte mit dieser Methode mehrere Attribute gleichzeitig hinzufügen, aber ich werde nur noch eines hinzufügen.

myRange = NSRange(location: 3, length: 17)
let anotherAttribute = [ NSAttributedString.Key.backgroundColor: UIColor.yellow ]
myString.addAttributes(anotherAttribute, range: myRange)

Geben Sie hier die Bildbeschreibung ein

Beachten Sie, dass sich die Attribute an einigen Stellen überlappen. Durch das Hinzufügen eines Attributs wird ein bereits vorhandenes Attribut nicht überschrieben.

verbunden

Weiterführende Literatur

Suragch
quelle
4
Beachten Sie, dass Sie verschiedene Stile zum Unterstreichen kombinieren können, z. B.NSUnderlineStyleAttributeName: NSUnderlineStyle.StyleSingle.rawValue | NSUnderlineStyle.PatternDot.rawValue
beeb
3
Sie können appendAttributedString nicht für NSAttributedString verwenden. Es muss sich für NSMutableAttributedString befinden. Können Sie Ihre Antwort aktualisieren, um dies widerzuspiegeln?
Joseph Astrahan
3
1) Super danke für deine Antwort. 2) Ich würde vorschlagen, dass Sie textView.atrributedtText = myStringoder myLabel.attributedText = myStringam Anfang Ihrer Antwort platzieren. Als Neuling habe ich es gerade getan myLabel.textund dachte nicht, dass ich all deine Antworten durchgehen müsste . ** 3) ** Bedeutet das, dass du nur eines haben kannst attributedTextoder textdass es bedeutungslos wäre, beide zu haben? 4) Ich empfehle, dass Sie auch ein lineSpacingBeispiel wie dieses in Ihre Antwort aufnehmen, da es sehr nützlich ist. 5) ачаар дахин
Honey
1
Der Unterschied zwischen Anhängen und Hinzufügen war zunächst verwirrend. appendAttributedStringist wie 'String-Verkettung'. addAttributefügt Ihrer Zeichenfolge ein neues Attribut hinzu.
Honig
2
@ Daniel, addAttributeist eine Methode von NSMutableAttributedString. Sie haben Recht, dass Sie es nicht mit Stringoder verwenden können NSAttributedString. (Überprüfen Sie die myStringDefinition im Abschnitt Ändern einermyStringNSAttributedString
zugewiesenen Zeichenfolge in
114

Swift verwendet dasselbe NSMutableAttributedStringwie Obj-C. Sie instanziieren es, indem Sie den berechneten Wert als Zeichenfolge übergeben:

var attributedString = NSMutableAttributedString(string:"\(calculatedCoffee)")

Erstellen Sie nun die zugeordnete gZeichenfolge (heh). Hinweis: UIFont.systemFontOfSize(_) ist jetzt ein fehlerhafter Initialisierer, daher muss er entpackt werden, bevor Sie ihn verwenden können:

var attrs = [NSFontAttributeName : UIFont.systemFontOfSize(19.0)!]
var gString = NSMutableAttributedString(string:"g", attributes:attrs)

Und dann anhängen:

attributedString.appendAttributedString(gString)

Sie können dann das UILabel so einstellen, dass der NSAttributedString wie folgt angezeigt wird:

myLabel.attributedText = attributedString
NRitH
quelle
//Part 1 Set Up The Lower Case g var coffeeText = NSMutableAttributedString(string:"\(calculateCoffee())") //Part 2 set the font attributes for the lower case g var coffeeTypeFaceAttributes = [NSFontAttributeName : UIFont.systemFontOfSize(18)] //Part 3 create the "g" character and give it the attributes var coffeeG = NSMutableAttributedString(string:"g", attributes:coffeeTypeFaceAttributes) Wenn ich mein UILabel.text = CoffeeText setze, erhalte ich die Fehlermeldung "NSMutableAttributedString kann nicht in 'String' konvertiert werden. Gibt es eine Möglichkeit, das UILabel dazu zu bringen, NSMutableAttributedString zu akzeptieren?
dcbenji
11
Wenn Sie eine zugeordnete Zeichenfolge haben, müssen Sie die Attribut-Attribut-Eigenschaft des Etiketts anstelle der Texteigenschaft festlegen.
NRitH
1
Dies hat richtig funktioniert und mein Kleinbuchstabe "g" wird jetzt an das Ende meines Kaffeemengen-Textes
angehängt
2
Aus irgendeinem Grund wird in meiner Zeile mit dem NSAttributedString die Fehlermeldung "Zusätzliches Argument beim Aufruf" angezeigt. Dies geschieht nur, wenn ich UIFont.systemFontOfSize (18) auf UIFont umstelle (Name: "Arial", Größe: 20). Irgendwelche Ideen?
Unome
UIFont (Name: Größe :) ist ein fehlgeschlagener Initialisierer und gibt möglicherweise null zurück. Sie können es entweder explizit auspacken, indem Sie hinzufügen! am Ende oder binden Sie es mit einer if / let-Anweisung an eine Variable, bevor Sie es in das Wörterbuch einfügen.
Asche
21

Xcode 6 Version :

let attriString = NSAttributedString(string:"attriString", attributes:
[NSForegroundColorAttributeName: UIColor.lightGrayColor(), 
            NSFontAttributeName: AttriFont])

Xcode 9.3 Version :

let attriString = NSAttributedString(string:"attriString", attributes:
[NSAttributedStringKey.foregroundColor: UIColor.lightGray, 
            NSAttributedStringKey.font: AttriFont])

Xcode 10, iOS 12, Swift 4 :

let attriString = NSAttributedString(string:"attriString", attributes:
[NSAttributedString.Key.foregroundColor: UIColor.lightGray, 
            NSAttributedString.Key.font: AttriFont])
Harthoo
quelle
20

Swift 4:

let attributes = [NSAttributedStringKey.font: UIFont(name: "HelveticaNeue-Bold", size: 17)!, 
                  NSAttributedStringKey.foregroundColor: UIColor.white]
Adam Bardon
quelle
es kompiliert nichtType 'NSAttributedStringKey' (aka 'NSString') has no member 'font'
bibscy
Ich habe es gerade in neuestem XCode (10 Beta 6) ausprobiert und es wird kompiliert. Sind Sie sicher, dass Sie Swift 4 verwenden?
Adam Bardon
Ich benutze Swift 3
bibscy
4
Nun, das ist das Problem, meine Antwort hat den fetten Titel "Swift 4". Ich empfehle Ihnen dringend, auf Swift 4
Adam Bardon
@bibscy können Sie NSAttributedString.Key verwenden. ***
Hatim
19

Ich würde wärmstens empfehlen, eine Bibliothek für zugeordnete Zeichenfolgen zu verwenden. Es macht es viel einfacher, wenn Sie beispielsweise eine Zeichenfolge mit vier verschiedenen Farben und vier verschiedenen Schriftarten möchten. Hier ist mein Favorit. Es heißt SwiftyAttributes

Wenn Sie mit SwiftyAttributes eine Zeichenfolge mit vier verschiedenen Farben und verschiedenen Schriftarten erstellen möchten:

let magenta = "Hello ".withAttributes([
    .textColor(.magenta),
    .font(.systemFont(ofSize: 15.0))
    ])
let cyan = "Sir ".withAttributes([
    .textColor(.cyan),
    .font(.boldSystemFont(ofSize: 15.0))
    ])
let green = "Lancelot".withAttributes([
    .textColor(.green),
    .font(.italicSystemFont(ofSize: 15.0))

    ])
let blue = "!".withAttributes([
    .textColor(.blue),
    .font(.preferredFont(forTextStyle: UIFontTextStyle.headline))

    ])
let finalString = magenta + cyan + green + blue

finalString würde zeigen als

Wird als Bild angezeigt

MendyK
quelle
15

Swift: xcode 6.1

    let font:UIFont? = UIFont(name: "Arial", size: 12.0)

    let attrString = NSAttributedString(
        string: titleData,
        attributes: NSDictionary(
            object: font!,
            forKey: NSFontAttributeName))
Vinod Joshi
quelle
10

Der beste Weg, um Attributed Strings unter iOS zu erreichen, ist die Verwendung des integrierten Attributed Text-Editors im Interface Builder und die Vermeidung unnötiger Hardcodierung von NSAtrributedStringKeys in Ihren Quelldateien.

Sie können Placehoderls später zur Laufzeit dynamisch ersetzen, indem Sie diese Erweiterung verwenden:

extension NSAttributedString {
    func replacing(placeholder:String, with valueString:String) -> NSAttributedString {

        if let range = self.string.range(of:placeholder) {
            let nsRange = NSRange(range,in:valueString)
            let mutableText = NSMutableAttributedString(attributedString: self)
            mutableText.replaceCharacters(in: nsRange, with: valueString)
            return mutableText as NSAttributedString
        }
        return self
    }
}

Fügen Sie ein Storyboard-Label mit zugeordnetem Text hinzu, der so aussieht.

Geben Sie hier die Bildbeschreibung ein

Dann aktualisieren Sie den Wert einfach jedes Mal, wenn Sie Folgendes benötigen:

label.attributedText = initalAttributedString.replacing(placeholder: "<price>", with: newValue)

Stellen Sie sicher, dass Sie den ursprünglichen Wert in initalAttributedString speichern.

Sie können diesen Ansatz besser verstehen, indem Sie diesen Artikel lesen: https://medium.com/mobile-appetite/text-attributes-on-ios-the-effortless-approach-ff086588173e

Efraim
quelle
Dies war sehr hilfreich für meinen Fall, in dem ich ein Storyboard hatte und nur einem Teil der Zeichenfolge in einem Etikett Fettdruck hinzufügen wollte. Viel einfacher als das manuelle Einrichten aller Attribute.
Marc Attinasi
Diese Erweiterung funktionierte früher perfekt für mich, aber in Xcode 11 stürzte meine App an der let nsRange = NSRange(range,in:valueString)Leitung ab.
Lucas P.
9

Swift 2.0

Hier ist ein Beispiel:

let newsString: NSMutableAttributedString = NSMutableAttributedString(string: "Tap here to read the latest Football News.")
newsString.addAttributes([NSUnderlineStyleAttributeName: NSUnderlineStyle.StyleDouble.rawValue], range: NSMakeRange(4, 4))
sampleLabel.attributedText = newsString.copy() as? NSAttributedString

Swift 5.x.

let newsString: NSMutableAttributedString = NSMutableAttributedString(string: "Tap here to read the latest Football News.")
newsString.addAttributes([NSAttributedString.Key.underlineStyle: NSUnderlineStyle.double.rawValue], range: NSMakeRange(4, 4))
sampleLabel.attributedText = newsString.copy() as? NSAttributedString

ODER

let stringAttributes = [
    NSFontAttributeName : UIFont(name: "Helvetica Neue", size: 17.0)!,
    NSUnderlineStyleAttributeName : 1,
    NSForegroundColorAttributeName : UIColor.orangeColor(),
    NSTextEffectAttributeName : NSTextEffectLetterpressStyle,
    NSStrokeWidthAttributeName : 2.0]
let atrributedString = NSAttributedString(string: "Sample String: Attributed", attributes: stringAttributes)
sampleLabel.attributedText = atrributedString
AG
quelle
8

Funktioniert gut in Beta 6

let attrString = NSAttributedString(
    string: "title-title-title",
    attributes: NSDictionary(
       object: NSFont(name: "Arial", size: 12.0), 
       forKey: NSFontAttributeName))
Andrey
quelle
7

Ich habe ein Online-Tool erstellt, das Ihr Problem lösen wird! Sie können Ihre Zeichenfolge schreiben und Stile grafisch anwenden. Das Tool bietet Ihnen Ziel-C und schnellen Code zum Generieren dieser Zeichenfolge.

Ist auch Open Source, also zögern Sie nicht, es zu erweitern und PRs zu senden.

Transformator-Werkzeug

Github

Geben Sie hier die Bildbeschreibung ein

Andres
quelle
Ich arbeite nicht für mich. Es wird einfach alles in Klammern gesetzt, ohne einen Stil anzuwenden.
Daniel Springer
5
func decorateText(sub:String, des:String)->NSAttributedString{
    let textAttributesOne = [NSAttributedStringKey.foregroundColor: UIColor.darkText, NSAttributedStringKey.font: UIFont(name: "PTSans-Bold", size: 17.0)!]
    let textAttributesTwo = [NSAttributedStringKey.foregroundColor: UIColor.black, NSAttributedStringKey.font: UIFont(name: "PTSans-Regular", size: 14.0)!]

    let textPartOne = NSMutableAttributedString(string: sub, attributes: textAttributesOne)
    let textPartTwo = NSMutableAttributedString(string: des, attributes: textAttributesTwo)

    let textCombination = NSMutableAttributedString()
    textCombination.append(textPartOne)
    textCombination.append(textPartTwo)
    return textCombination
}

//Implementierung

cell.lblFrom.attributedText = decorateText(sub: sender!, des: " - \(convertDateFormatShort3(myDateString: datetime!))")
Yogesh Tandel
quelle
5

Swift 5 und höher

   let attributedString = NSAttributedString(string:"targetString",
                                   attributes:[NSAttributedString.Key.foregroundColor: UIColor.lightGray,
                                               NSAttributedString.Key.font: UIFont(name: "Arial", size: 18.0) as Any])
midhun p
quelle
4

Swift 4

let attributes = [NSAttributedStringKey.font : UIFont(name: CustomFont.NAME_REGULAR.rawValue, size: CustomFontSize.SURVEY_FORM_LABEL_SIZE.rawValue)!]

let attributedString : NSAttributedString = NSAttributedString(string: messageString, attributes: attributes)

Sie müssen den Rohwert in Swift 4 entfernen

Neha
quelle
3

Für mich haben die oben genannten Lösungen beim Festlegen einer bestimmten Farbe oder Eigenschaft nicht funktioniert.

Das hat funktioniert:

let attributes = [
    NSFontAttributeName : UIFont(name: "Helvetica Neue", size: 12.0)!,
    NSUnderlineStyleAttributeName : 1,
    NSForegroundColorAttributeName : UIColor.darkGrayColor(),
    NSTextEffectAttributeName : NSTextEffectLetterpressStyle,
    NSStrokeWidthAttributeName : 3.0]

var atriString = NSAttributedString(string: "My Attributed String", attributes: attributes)
Swennemen
quelle
3

Swift 2.1 - Xcode 7

let labelFont = UIFont(name: "HelveticaNeue-Bold", size: 18)
let attributes :[String:AnyObject] = [NSFontAttributeName : labelFont!]
let attrString = NSAttributedString(string:"foo", attributes: attributes)
myLabel.attributedText = attrString
Alessandro Ornano
quelle
Welche Änderungen wurden zwischen Swift 2.0 und 2.1 vorgenommen?
Suragch
3

Verwenden Sie diesen Beispielcode. Dies ist ein sehr kurzer Code, um Ihre Anforderung zu erfüllen. Das funktioniert bei mir.

let attributes = [NSAttributedStringKey.font : UIFont(name: CustomFont.NAME_REGULAR.rawValue, size: CustomFontSize.SURVEY_FORM_LABEL_SIZE.rawValue)!]

let attributedString : NSAttributedString = NSAttributedString(string: messageString, attributes: attributes)
VipinYadav
quelle
2
extension UILabel{
    func setSubTextColor(pSubString : String, pColor : UIColor){    
        let attributedString: NSMutableAttributedString = self.attributedText != nil ? NSMutableAttributedString(attributedString: self.attributedText!) : NSMutableAttributedString(string: self.text!);

        let range = attributedString.mutableString.range(of: pSubString, options:NSString.CompareOptions.caseInsensitive)
        if range.location != NSNotFound {
            attributedString.addAttribute(NSForegroundColorAttributeName, value: pColor, range: range);
        }
        self.attributedText = attributedString
    }
}
Dipak Panchasara
quelle
cell.IBLabelGuestAppointmentTime.text = "\ n \ nGuest1 \ n8: 00 Uhr \ n \ nGast2 \ n9: 00Am \ n \ n" cell.IBLabelGuestAppointmentTime.setSubTextColor (pSubString: "Guest1", pColor: UIColor .setSubTextColor (pSubString: "Guest2", pColor: UIColor.red)
Dipak Panchasara
1
Willkommen bei SO. Bitte formatieren Sie Ihren Code und fügen Sie Ihrer Antwort eine Erklärung / einen Kontext hinzu. Siehe: stackoverflow.com/help/how-to-answer
Uwe Allner
2

Die Attribute können direkt in Swift 3 ...

    let attributes = NSAttributedString(string: "String", attributes: [NSFontAttributeName : UIFont(name: "AvenirNext-Medium", size: 30)!,
         NSForegroundColorAttributeName : UIColor .white,
         NSTextEffectAttributeName : NSTextEffectLetterpressStyle])

Verwenden Sie dann die Variable in einer beliebigen Klasse mit Attributen

Sebastian
quelle
2

Swift 4.2

extension UILabel {

    func boldSubstring(_ substr: String) {
        guard substr.isEmpty == false,
            let text = attributedText,
            let range = text.string.range(of: substr, options: .caseInsensitive) else {
                return
        }
        let attr = NSMutableAttributedString(attributedString: text)
        let start = text.string.distance(from: text.string.startIndex, to: range.lowerBound)
        let length = text.string.distance(from: range.lowerBound, to: range.upperBound)
        attr.addAttributes([NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: self.font.pointSize)],
                           range: NSMakeRange(start, length))
        attributedText = attr
    }
}
Debaprio B.
quelle
Warum nicht einfach range.count für die Länge?
Leo Dabus
2

Einzelheiten

  • Swift 5.2, Xcode 11.4 (11E146)

Lösung

protocol AttributedStringComponent {
    var text: String { get }
    func getAttributes() -> [NSAttributedString.Key: Any]?
}

// MARK: String extensions

extension String: AttributedStringComponent {
    var text: String { self }
    func getAttributes() -> [NSAttributedString.Key: Any]? { return nil }
}

extension String {
    func toAttributed(with attributes: [NSAttributedString.Key: Any]?) -> NSAttributedString {
        .init(string: self, attributes: attributes)
    }
}

// MARK: NSAttributedString extensions

extension NSAttributedString: AttributedStringComponent {
    var text: String { string }

    func getAttributes() -> [Key: Any]? {
        if string.isEmpty { return nil }
        var range = NSRange(location: 0, length: string.count)
        return attributes(at: 0, effectiveRange: &range)
    }
}

extension NSAttributedString {

    convenience init?(from attributedStringComponents: [AttributedStringComponent],
                      defaultAttributes: [NSAttributedString.Key: Any],
                      joinedSeparator: String = " ") {
        switch attributedStringComponents.count {
        case 0: return nil
        default:
            var joinedString = ""
            typealias SttributedStringComponentDescriptor = ([NSAttributedString.Key: Any], NSRange)
            let sttributedStringComponents = attributedStringComponents.enumerated().flatMap { (index, component) -> [SttributedStringComponentDescriptor] in
                var components = [SttributedStringComponentDescriptor]()
                if index != 0 {
                    components.append((defaultAttributes,
                                       NSRange(location: joinedString.count, length: joinedSeparator.count)))
                    joinedString += joinedSeparator
                }
                components.append((component.getAttributes() ?? defaultAttributes,
                                   NSRange(location: joinedString.count, length: component.text.count)))
                joinedString += component.text
                return components
            }

            let attributedString = NSMutableAttributedString(string: joinedString)
            sttributedStringComponents.forEach { attributedString.addAttributes($0, range: $1) }
            self.init(attributedString: attributedString)
        }
    }
}

Verwendungszweck

let defaultAttributes = [
    .font: UIFont.systemFont(ofSize: 16, weight: .regular),
    .foregroundColor: UIColor.blue
] as [NSAttributedString.Key : Any]

let marketingAttributes = [
    .font: UIFont.systemFont(ofSize: 20.0, weight: .bold),
    .foregroundColor: UIColor.black
] as [NSAttributedString.Key : Any]

let attributedStringComponents = [
    "pay for",
    NSAttributedString(string: "one",
                       attributes: marketingAttributes),
    "and get",
    "three!\n".toAttributed(with: marketingAttributes),
    "Only today!".toAttributed(with: [
        .font: UIFont.systemFont(ofSize: 16.0, weight: .bold),
        .foregroundColor: UIColor.red
    ])
] as [AttributedStringComponent]
let attributedText = NSAttributedString(from: attributedStringComponents, defaultAttributes: defaultAttributes)

Vollständiges Beispiel

Vergessen Sie nicht, den Lösungscode hier einzufügen

import UIKit

class ViewController: UIViewController {

    private weak var label: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
        let label = UILabel(frame: .init(x: 40, y: 40, width: 300, height: 80))
        label.numberOfLines = 2
        view.addSubview(label)
        self.label = label

        let defaultAttributes = [
            .font: UIFont.systemFont(ofSize: 16, weight: .regular),
            .foregroundColor: UIColor.blue
        ] as [NSAttributedString.Key : Any]

        let marketingAttributes = [
            .font: UIFont.systemFont(ofSize: 20.0, weight: .bold),
            .foregroundColor: UIColor.black
        ] as [NSAttributedString.Key : Any]

        let attributedStringComponents = [
            "pay for",
            NSAttributedString(string: "one",
                               attributes: marketingAttributes),
            "and get",
            "three!\n".toAttributed(with: marketingAttributes),
            "Only today!".toAttributed(with: [
                .font: UIFont.systemFont(ofSize: 16.0, weight: .bold),
                .foregroundColor: UIColor.red
            ])
        ] as [AttributedStringComponent]
        label.attributedText = NSAttributedString(from: attributedStringComponents, defaultAttributes: defaultAttributes)
        label.textAlignment = .center
    }
}

Ergebnis

Geben Sie hier die Bildbeschreibung ein

Wassili Bodnarchuk
quelle
1

Mit der von mir erstellten Bibliothek können Sie Ihr Problem ganz einfach lösen. Es heißt Atributika.

let calculatedCoffee: Int = 768
let g = Style("g").font(.boldSystemFont(ofSize: 12)).foregroundColor(.red)
let all = Style.font(.systemFont(ofSize: 12))

let str = "\(calculatedCoffee)<g>g</g>".style(tags: g)
    .styleAll(all)
    .attributedString

label.attributedText = str

768 g

Sie finden es hier https://github.com/psharanda/Atributika

Pavel Sharanda
quelle
1
 let attrString = NSAttributedString (
            string: "title-title-title",
            attributes: [NSAttributedStringKey.foregroundColor: UIColor.black])
Eugene Braginets
quelle
1

Swifter Swift hat eine ziemlich süße Art, dies ohne Arbeit zu tun. Geben Sie einfach das Muster an, das übereinstimmen soll, und welche Attribute darauf angewendet werden sollen. Sie sind großartig für viele Dinge, die sie ausprobieren.

``` Swift
let defaultGenreText = NSAttributedString(string: "Select Genre - Required")
let redGenreText = defaultGenreText.applying(attributes: [NSAttributedString.Key.foregroundColor : UIColor.red], toRangesMatching: "Required")
``

Wenn Sie mehrere Stellen haben, an denen dies angewendet wird, und Sie möchten, dass dies nur für bestimmte Instanzen geschieht, funktioniert diese Methode nicht.

Sie können dies in einem Schritt tun, der beim Trennen einfacher zu lesen ist.

Vrezh Gulyan
quelle
0

Swift 4.x.

let attr = [NSForegroundColorAttributeName:self.configuration.settingsColor, NSFontAttributeName: self.configuration.settingsFont]

let title = NSAttributedString(string: self.configuration.settingsTitle,
                               attributes: attr)
Arunabh Das
quelle
0

Swift 3.0 // Attributzeichenfolge erstellen

Definieren Sie Attribute wie

let attributes = [NSAttributedStringKey.font : UIFont.init(name: "Avenir-Medium", size: 13.0)]
iOS Entwickler
quelle
0

Bitte erwägen Sie die Verwendung von Prestyler

import Prestyler
...
Prestyle.defineRule("$", UIColor.red)
label.attributedText = "\(calculatedCoffee) $g$".prestyled()
Kruiller
quelle
0

Swift 5

    let attrStri = NSMutableAttributedString.init(string:"This is red")
    let nsRange = NSString(string: "This is red").range(of: "red", options: String.CompareOptions.caseInsensitive)
    attrStri.addAttributes([NSAttributedString.Key.foregroundColor : UIColor.red, NSAttributedString.Key.font: UIFont.init(name: "PTSans-Regular", size: 15.0) as Any], range: nsRange)
    self.label.attributedText = attrStri

Geben Sie hier die Bildbeschreibung ein

Gurjinder Singh
quelle
-4
extension String {
//MARK: Getting customized string
struct StringAttribute {
    var fontName = "HelveticaNeue-Bold"
    var fontSize: CGFloat?
    var initialIndexOftheText = 0
    var lastIndexOftheText: Int?
    var textColor: UIColor = .black
    var backGroundColor: UIColor = .clear
    var underLineStyle: NSUnderlineStyle = .styleNone
    var textShadow: TextShadow = TextShadow()

    var fontOfText: UIFont {
        if let font = UIFont(name: fontName, size: fontSize!) {
            return font
        } else {
            return UIFont(name: "HelveticaNeue-Bold", size: fontSize!)!
        }
    }

    struct TextShadow {
        var shadowBlurRadius = 0
        var shadowOffsetSize = CGSize(width: 0, height: 0)
        var shadowColor: UIColor = .clear
    }
}
func getFontifiedText(partOfTheStringNeedToConvert partTexts: [StringAttribute]) -> NSAttributedString {
    let fontChangedtext = NSMutableAttributedString(string: self, attributes: [NSFontAttributeName: UIFont(name: "HelveticaNeue-Bold", size: (partTexts.first?.fontSize)!)!])
    for eachPartText in partTexts {
        let lastIndex = eachPartText.lastIndexOftheText ?? self.count
        let attrs = [NSFontAttributeName : eachPartText.fontOfText, NSForegroundColorAttributeName: eachPartText.textColor, NSBackgroundColorAttributeName: eachPartText.backGroundColor, NSUnderlineStyleAttributeName: eachPartText.underLineStyle, NSShadowAttributeName: eachPartText.textShadow ] as [String : Any]
        let range = NSRange(location: eachPartText.initialIndexOftheText, length: lastIndex - eachPartText.initialIndexOftheText)
        fontChangedtext.addAttributes(attrs, range: range)
    }
    return fontChangedtext
}

}}

// Benutze es wie unten

    let someAttributedText = "Some   Text".getFontifiedText(partOfTheStringNeedToConvert: <#T##[String.StringAttribute]#>)
Manas Mishra
quelle
2
Diese Antwort enthält alles, was Sie wissen müssen, außer wie Sie schnell eine zugeordnete Zeichenfolge erstellen.
Eric