Rendere il testo in grassetto usando la stringa attribuita in swift


100

Ho una stringa come questa

var str = "@text1 this is good @text1"

Ora sostituisci text1con un'altra stringa, diciamo t 1. Sono in grado di sostituire il testo, ma non sono in grado di metterlo in grassetto. Voglio mettere in grassetto la nuova stringa t 1, in modo che l'output finale sarà:

@t 1 questo è buono @t 1

Come posso farlo?

Tutti gli esempi che vedo sono in Objective-C, ma voglio farlo in Swift.

Grazie in anticipo.


1
Devi scomporre il tuo problema: Scopri come "grassetto": stackoverflow.com/questions/25199580/… Scopri come sostituire il testo.
Larme

1
Usa questa libreria, è semplicissimo. github.com/iOSTechHub/AttributedString
Ashish Chauhan

Risposte:


237

Utilizzo:

let label = UILabel()
label.attributedText =
    NSMutableAttributedString()
        .bold("Address: ")
        .normal(" Kathmandu, Nepal\n\n")
        .orangeHighlight(" Email: ")
        .blackHighlight(" prajeet.shrestha@gmail.com ")
        .bold("\n\nCopyright: ")
        .underlined(" All rights reserved. 2020.")

Risultato:

inserisci qui la descrizione dell'immagine

Ecco un modo accurato per creare una combinazione di testi in grassetto e normali in un'unica etichetta più altri metodi bonus.

Estensione: Swift 5. *

extension NSMutableAttributedString {
    var fontSize:CGFloat { return 14 }
    var boldFont:UIFont { return UIFont(name: "AvenirNext-Bold", size: fontSize) ?? UIFont.boldSystemFont(ofSize: fontSize) }
    var normalFont:UIFont { return UIFont(name: "AvenirNext-Regular", size: fontSize) ?? UIFont.systemFont(ofSize: fontSize)}

    func bold(_ value:String) -> NSMutableAttributedString {

        let attributes:[NSAttributedString.Key : Any] = [
            .font : boldFont
        ]

        self.append(NSAttributedString(string: value, attributes:attributes))
        return self
    }

    func normal(_ value:String) -> NSMutableAttributedString {

        let attributes:[NSAttributedString.Key : Any] = [
            .font : normalFont,
        ]

        self.append(NSAttributedString(string: value, attributes:attributes))
        return self
    }
    /* Other styling methods */
    func orangeHighlight(_ value:String) -> NSMutableAttributedString {

        let attributes:[NSAttributedString.Key : Any] = [
            .font :  normalFont,
            .foregroundColor : UIColor.white,
            .backgroundColor : UIColor.orange
        ]

        self.append(NSAttributedString(string: value, attributes:attributes))
        return self
    }

    func blackHighlight(_ value:String) -> NSMutableAttributedString {

        let attributes:[NSAttributedString.Key : Any] = [
            .font :  normalFont,
            .foregroundColor : UIColor.white,
            .backgroundColor : UIColor.black

        ]

        self.append(NSAttributedString(string: value, attributes:attributes))
        return self
    }

    func underlined(_ value:String) -> NSMutableAttributedString {

        let attributes:[NSAttributedString.Key : Any] = [
            .font :  normalFont,
            .underlineStyle : NSUnderlineStyle.single.rawValue

        ]

        self.append(NSAttributedString(string: value, attributes:attributes))
        return self
    }
}

non è per swift 2?
remy boys

2
Una piccola aggiunta: func bold(_ text:String, _ size:CGFloat). Ho aggiunto le dimensioni al grassetto in modo da poterlo controllare dall'esterno. Inoltre, ho perso il AvenirNext-Mediumcarattere in questa funzione, quindi mi ci sono voluti alcuni minuti per capire perché non riesco a vedere il mio carattere. Dritta.
Gal

mi hai salvato la giornata, amico!
oskarko

Grazie! Ha funzionato a meraviglia :)
Sharad Chauhan

1
Ballay ballay sarkaaar: D
Mohsin Khubaib Ahmed

102
var normalText = "Hi am normal"

var boldText  = "And I am BOLD!"

var attributedString = NSMutableAttributedString(string:normalText)

var attrs = [NSFontAttributeName : UIFont.boldSystemFont(ofSize: 15)]
var boldString = NSMutableAttributedString(string: boldText, attributes:attrs)

attributedString.append(boldString)

Quando vuoi assegnarlo a un'etichetta:

yourLabel.attributedText = attributedString

Risposta fantastica! Grazie!
hacker_1989

nota: appendAttributedString è stato rinominato in .append ()
Andrea Leganza

28

modifica / aggiornamento: Xcode 8.3.2 • Swift 3.1

Se conosci HTML e CSS puoi usarlo per controllare facilmente lo stile del carattere, il colore e la dimensione della tua stringa attribuita come segue:

extension String {
    var html2AttStr: NSAttributedString? {
        return try? NSAttributedString(data: Data(utf8), options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue], documentAttributes: nil)
    }
}

"<style type=\"text/css\">#red{color:#F00}#green{color:#0F0}#blue{color: #00F; font-weight: Bold; font-size: 32}</style><span id=\"red\" >Red,</span><span id=\"green\" > Green </span><span id=\"blue\">and Blue</span>".html2AttStr

Sto cercando di implementarlo in Swift 2 Xcode, ma il carattere non viene applicato. Ecco la stringa: <link href=\"https://fonts.googleapis.com/css?family=Frank+Ruhl+Libre\" rel=\"stylesheet\"> <span style=\"font-family: 'Frank Ruhl Libre', sans-serif;\">שלום</span>
DaniSmithProductions

Se utilizza lo stile WebKit per analizzare le stringhe HTML in NSAttributedString, fare attenzione a usarlo in un thread in background ...
FouZ

Quali sono i vantaggi dell'utilizzo di questo approccio piuttosto che della risposta @prajeet?
Emre Önder

17

Se stai lavorando con stringhe localizzate, potresti non essere in grado di fare affidamento sul fatto che la stringa in grassetto si trovi sempre alla fine della frase. In questo caso, funziona bene quanto segue:

ad esempio, la query "blah" non corrisponde ad alcun elemento

/* Create the search query part of the text, e.g. "blah". 
   The variable 'text' is just the value entered by  the user. */
let searchQuery = "\"\(text)\""

/* Put the search text into the message */
let message = "Query \(searchQuery). does not match any items"

/* Find the position of the search string. Cast to NSString as we want
   range to be of type NSRange, not Swift's Range<Index> */
let range = (message as NSString).rangeOfString(searchQuery)

/* Make the text at the given range bold. Rather than hard-coding a text size,
   Use the text size configured in Interface Builder. */
let attributedString = NSMutableAttributedString(string: message)
attributedString.addAttribute(NSFontAttributeName, value: UIFont.boldSystemFontOfSize(label.font.pointSize), range: range)

/* Put the text in a label */
label.attributedText = attributedString

2
Dopo ore di ricerca, questa è l'unica risposta che ha trovato una soluzione al mio problema. +1
Super_Simon

9

Ho esteso l'ottima risposta di David West in modo che tu possa inserire una stringa e dirgli tutte le sottostringhe che vorresti incoraggiare:

func addBoldText(fullString: NSString, boldPartsOfString: Array<NSString>, font: UIFont!, boldFont: UIFont!) -> NSAttributedString {
    let nonBoldFontAttribute = [NSFontAttributeName:font!]
    let boldFontAttribute = [NSFontAttributeName:boldFont!]
    let boldString = NSMutableAttributedString(string: fullString as String, attributes:nonBoldFontAttribute)
    for i in 0 ..< boldPartsOfString.count {
        boldString.addAttributes(boldFontAttribute, range: fullString.rangeOfString(boldPartsOfString[i] as String))
    }
    return boldString
}

E poi chiamalo così:

let normalFont = UIFont(name: "Dosis-Medium", size: 18)
let boldSearchFont = UIFont(name: "Dosis-Bold", size: 18)
self.UILabel.attributedText = addBoldText("Check again in 30 days to find more friends", boldPartsOfString: ["Check", "30 days", "find", "friends"], font: normalFont!, boldFont: boldSearchFont!)

Questo rafforzerà tutte le sottostringhe che vuoi mettere in grassetto nella stringa data


È possibile avere la stessa parola in grassetto in due punti diversi? EX: "Controlla di nuovo tra 30 giorni per trovare 30 amici". Come si rendono audaci entrambi i "30"? Grazie in anticipo.
Dian

8

Questo è il modo migliore che ho escogitato. Aggiungi una funzione che puoi chiamare da qualsiasi luogo e aggiungila a un file senza una classe come Constants.swift e quindi puoi incoraggiare le parole all'interno di qualsiasi stringa, in numerose occasioni chiamando solo UNA LINEA di codice:

Per entrare in un file constants.swift:

import Foundation
import UIKit

func addBoldText(fullString: NSString, boldPartOfString: NSString, font: UIFont!, boldFont: UIFont!) -> NSAttributedString {
   let nonBoldFontAttribute = [NSFontAttributeName:font!]
   let boldFontAttribute = [NSFontAttributeName:boldFont!]
   let boldString = NSMutableAttributedString(string: fullString as String, attributes:nonBoldFontAttribute)
   boldString.addAttributes(boldFontAttribute, range: fullString.rangeOfString(boldPartOfString as String))
   return boldString
}

Quindi puoi semplicemente chiamare questa riga di codice per qualsiasi UILabel:

self.UILabel.attributedText = addBoldText("Check again in 30 DAYS to find more friends", boldPartOfString: "30 DAYS", font: normalFont!, boldFont: boldSearchFont!)


//Mark: Albeit that you've had to define these somewhere:

let normalFont = UIFont(name: "INSERT FONT NAME", size: 15)
let boldFont = UIFont(name: "INSERT BOLD FONT", size: 15)

8

Basandosi sulle eccellenti risposte di Jeremy Bader e David West, un'estensione di Swift 3:

extension String {
    func withBoldText(boldPartsOfString: Array<NSString>, font: UIFont!, boldFont: UIFont!) -> NSAttributedString {
        let nonBoldFontAttribute = [NSFontAttributeName:font!]
        let boldFontAttribute = [NSFontAttributeName:boldFont!]
        let boldString = NSMutableAttributedString(string: self as String, attributes:nonBoldFontAttribute)
        for i in 0 ..< boldPartsOfString.count {
            boldString.addAttributes(boldFontAttribute, range: (self as NSString).range(of: boldPartsOfString[i] as String))
        }
        return boldString
    }
}

Utilizzo:

let label = UILabel()
let font = UIFont(name: "AvenirNext-Italic", size: 24)!
let boldFont = UIFont(name: "AvenirNext-BoldItalic", size: 24)!
label.attributedText = "Make sure your face is\nbrightly and evenly lit".withBoldText(
    boldPartsOfString: ["brightly", "evenly"], font: font, boldFont: boldFont)

5

utilizzo ....

let attrString = NSMutableAttributedString()
            .appendWith(weight: .semibold, "almost bold")
            .appendWith(color: .white, weight: .bold, " white and bold")
            .appendWith(color: .black, ofSize: 18.0, " big black")

due centesimi ...

extension NSMutableAttributedString {

    @discardableResult func appendWith(color: UIColor = UIColor.darkText, weight: UIFont.Weight = .regular, ofSize: CGFloat = 12.0, _ text: String) -> NSMutableAttributedString{
        let attrText = NSAttributedString.makeWith(color: color, weight: weight, ofSize:ofSize, text)
        self.append(attrText)
        return self
    }

}
extension NSAttributedString {

    public static func makeWith(color: UIColor = UIColor.darkText, weight: UIFont.Weight = .regular, ofSize: CGFloat = 12.0, _ text: String) -> NSMutableAttributedString {

        let attrs = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: ofSize, weight: weight), NSAttributedStringKey.foregroundColor: color]
        return NSMutableAttributedString(string: text, attributes:attrs)
    }
}

1
iOS 11 o versioni successive (a causa dell'utilizzo di UIFont.Weight).
Andrea Leganza

4

Accettando come valida la risposta di Prajeet Shrestha in questo thread, vorrei estendere la sua soluzione utilizzando l'etichetta se è nota ei tratti del carattere.

Swift 4

extension NSMutableAttributedString {

    @discardableResult func normal(_ text: String) -> NSMutableAttributedString {
        let normal = NSAttributedString(string: text)
        append(normal)

        return self
    }

    @discardableResult func bold(_ text: String, withLabel label: UILabel) -> NSMutableAttributedString {

        //generate the bold font
        var font: UIFont = UIFont(name: label.font.fontName , size: label.font.pointSize)!
        font = UIFont(descriptor: font.fontDescriptor.withSymbolicTraits(.traitBold) ?? font.fontDescriptor, size: font.pointSize)

        //generate attributes
        let attrs: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: font]
        let boldString = NSMutableAttributedString(string:text, attributes: attrs)

        //append the attributed text
        append(boldString)

        return self
    }
}

4

Swift 4 e versioni successive

Per Swift 4 e versioni successive questo è un buon metodo:

    let attributsBold = [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16, weight: .bold)]
    let attributsNormal = [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16, weight: .regular)]
    var attributedString = NSMutableAttributedString(string: "Hi ", attributes:attributsNormal)
    let boldStringPart = NSMutableAttributedString(string: "John", attributes:attributsBold)
    attributedString.append(boldStringPart)
  
    yourLabel.attributedText = attributedString

Nell'etichetta il testo appare come: "Ciao John "


3

Un modo semplicissimo per farlo.

    let text = "This string is having multiple font"
    let attributedText = 
    NSMutableAttributedString.getAttributedString(fromString: text)

    attributedText.apply(font: UIFont.boldSystemFont(ofSize: 24), subString: 
    "This")

    attributedText.apply(font: UIFont.boldSystemFont(ofSize: 24), onRange: 
    NSMakeRange(5, 6))

Per maggiori dettagli fare clic qui: https://github.com/iOSTechHub/AttributedString


Che ne dici di semi grassetto?
Houman

Questa dovrebbe essere la risposta accettata. @Houman usa la libreria sopra e usa il applymetodo con il carattere che desideri
Zack Shapiro

2

Questo potrebbe essere utile

class func createAttributedStringFrom (string1 : String ,strin2 : String, attributes1 : Dictionary<String, NSObject>, attributes2 : Dictionary<String, NSObject>) -> NSAttributedString{

let fullStringNormal = (string1 + strin2) as NSString
let attributedFullString = NSMutableAttributedString(string: fullStringNormal as String)

attributedFullString.addAttributes(attributes1, range: fullStringNormal.rangeOfString(string1))
attributedFullString.addAttributes(attributes2, range: fullStringNormal.rangeOfString(strin2))
return attributedFullString
}

2

Swift 3.0

Converti html in stringhe e cambia carattere secondo le tue esigenze.

do {

     let str = try NSAttributedString(data: ("I'm a normal text and <b>this is my bold part . </b>And I'm again in the normal text".data(using: String.Encoding.unicode, allowLossyConversion: true)!), options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil)

     myLabel.attributedText = str
     myLabel.font =  MONTSERRAT_BOLD(23)
     myLabel.textAlignment = NSTextAlignment.left
} catch {
     print(error)
}


func MONTSERRAT_BOLD(_ size: CGFloat) -> UIFont
{
    return UIFont(name: "MONTSERRAT-BOLD", size: size)!
}

Dovresti convertire la tua stringa in dati usando utf8. Tieni presente che i dati sono conformi alla raccolta in Swift 3, quindi puoi inizializzare i dati con la visualizzazione della raccolta della stringa utf8 Data("I'm a normal text and <b>this is my bold part . </b>And I'm again in the normal text".utf8)e impostare la codifica dei caratteri nelle opzioni[NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue]
Leo Dabus

0

Basta usare un codice simile a questo:

 let font = UIFont(name: "Your-Font-Name", size: 10.0)!

        let attributedText = NSMutableAttributedString(attributedString: noteLabel.attributedText!)
        let boldedRange = NSRange(attributedText.string.range(of: "Note:")!, in: attributedText.string)
        attributedText.addAttributes([NSAttributedString.Key.font : font], range: boldedRange)
        noteLabel.attributedText = attributedText

0

due linee in swift 4:

            button.setAttributedTitle(.init(string: "My text", attributes: [.font: UIFont.systemFont(ofSize: 20, weight: .bold)]), for: .selected)
            button.setAttributedTitle(.init(string: "My text", attributes: [.font: UIFont.systemFont(ofSize: 20, weight: .regular)]), for: .normal)

0

Swift 5.1 usa NSAttributedString.Keyinvece diNSAttributedStringKey

let test1Attributes:[NSAttributedString.Key: Any] = [.font : UIFont(name: "CircularStd-Book", size: 14)!]
let test2Attributes:[NSAttributedString.Key: Any] = [.font : UIFont(name: "CircularStd-Bold", size: 16)!]

let test1 = NSAttributedString(string: "\(greeting!) ", attributes:test1Attributes)
let test2 = NSAttributedString(string: firstName!, attributes:test2Attributes)
let text = NSMutableAttributedString()

text.append(test1)
text.append(test2)
return text

0

Per -> Cerca nella televisione per dimensione

1 via utilizzando NString e il suo intervallo

let query = "Television"
let headerTitle = "size"
let message = "Search \(query) by \(headerTitle)"
let range = (message as NSString).range(of: query)
let attributedString = NSMutableAttributedString(string: message)
attributedString.addAttribute(NSAttributedString.Key.font, value: UIFont.boldSystemFont(ofSize: label1.font.pointSize), range: range)
label1.attributedText = attributedString

un altro senza usare NString e il suo intervallo

let query = "Television"
let headerTitle = "size"
let (searchText, byText) = ("Search ", " by \(headerTitle)")
let attributedString = NSMutableAttributedString(string: searchText)
let byTextAttributedString = NSMutableAttributedString(string: byText)
let attrs = [NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: label1.font.pointSize)]
let boldString = NSMutableAttributedString(string: query, attributes:attrs)
attributedString.append(boldString)
attributedString.append(byTextAttributedString)
label1.attributedText = attributedString

swift5


-1

Migliorare la risposta di Prajeet Shrestha: -

Puoi creare un'estensione generica per NSMutableAttributedString che coinvolge meno codice. In questo caso ho scelto di utilizzare il carattere di sistema ma potresti adattarlo in modo da poter inserire il nome del carattere come parametro.

    extension NSMutableAttributedString {

        func systemFontWith(text: String, size: CGFloat, weight: CGFloat) -> NSMutableAttributedString {
            let attributes: [String: AnyObject] = [NSFontAttributeName: UIFont.systemFont(ofSize: size, weight: weight)]
            let string = NSMutableAttributedString(string: text, attributes: attributes)
            self.append(string)
            return self
        }
    }

-1

Puoi farlo usando un semplice metodo personalizzato scritto di seguito. Devi dare l'intera stringa nel primo parametro e il testo in grassetto nel secondo parametro. Spero che questo ti aiuti.

func getAttributedBoldString(str : String, boldTxt : String) -> NSMutableAttributedString {
        let attrStr = NSMutableAttributedString.init(string: str)
        let boldedRange = NSRange(str.range(of: boldTxt)!, in: str)
        attrStr.addAttributes([NSAttributedString.Key.font : UIFont.systemFont(ofSize: 17, weight: .bold)], range: boldedRange)
        return attrStr
    }

utilizzo: initalString = Sono un ragazzo

label.attributedText = getAttributedBoldString (str: initalString, boldTxt: "Boy")

stringa risultante = Sono un ragazzo

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.