Poner el texto en negrita usando una cadena atribuida en rápido

100

Tengo una cuerda como esta

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

Ahora reemplace text1con otra cadena, digamos t 1. Puedo reemplazar el texto, pero no puedo ponerlo en negrita. Quiero poner en negrita la nueva cadena t 1, para que la salida final sea:

@t 1 esto es bueno @t 1

¿Cómo puedo hacerlo?

Todos los ejemplos que estoy viendo están en Objective-C, pero quiero hacerlo en Swift.

Gracias por adelantado.

usuario2413621
fuente
1
Necesita descomponer su problema: Aprenda a poner "negrita": stackoverflow.com/questions/25199580/… Aprenda a reemplazar texto.
Larme
1
Utilice esta biblioteca, es insignificante. github.com/iOSTechHub/AttributedString
Ashish Chauhan

Respuestas:

235

Uso:

let label = UILabel()
label.attributedText =
    NSMutableAttributedString()
        .bold("Address: ")
        .normal(" Kathmandu, Nepal\n\n")
        .orangeHighlight(" Email: ")
        .blackHighlight(" [email protected] ")
        .bold("\n\nCopyright: ")
        .underlined(" All rights reserved. 2020.")

Resultado:

ingrese la descripción de la imagen aquí

Aquí hay una forma ordenada de hacer una combinación de textos normales y en negrita en una sola etiqueta más algunos otros métodos adicionales.

Extensión: 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
    }
}
Prajeet Shrestha
fuente
¿No es para Swift 2?
remy boys
2
Una pequeña adición: func bold(_ text:String, _ size:CGFloat). Agregué tamaño al negrita para poder controlarlo desde afuera. Además, me perdí la AvenirNext-Mediumfuente en esta función, así que me tomó unos minutos entender por qué no puedo ver mi fuente. Aviso.
Gal
me salvaste el día, amigo!
oskarko
¡Gracias! Funcionó como el encanto :)
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)

Cuando desee asignarlo a una etiqueta:

yourLabel.attributedText = attributedString
Dejan Skledar
fuente
¡Respuesta impresionante! ¡Gracias!
hacker_1989
nota: appendAttributedString ha sido renombrado a .append ()
Andrea Leganza
28

editar / actualizar: Xcode 8.3.2 • Swift 3.1

Si conoce HTML y CSS, puede usarlo para controlar fácilmente el estilo de fuente, el color y el tamaño de su cadena atribuida de la siguiente manera:

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
Leo Dabus
fuente
Estoy tratando de implementar esto en Swift 2 Xcode, pero la fuente no se está aplicando. Aquí está la cadena: <link href=\"https://fonts.googleapis.com/css?family=Frank+Ruhl+Libre\" rel=\"stylesheet\"> <span style=\"font-family: 'Frank Ruhl Libre', sans-serif;\">שלום</span>
DaniSmithProductions
Si usa WebKit para analizar cadenas HTML en NSAttributedString, tenga cuidado al usarlo en un hilo de fondo ...
FouZ
¿Cuáles son los beneficios de usar este enfoque en lugar de la respuesta de @prajeet?
Emre Önder
17

Si está trabajando con cadenas localizadas, es posible que no pueda confiar en que la cadena en negrita esté siempre al final de la oración. Si este es el caso, lo siguiente funciona bien:

por ejemplo, la consulta "bla" no coincide con ningún 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
Ian
fuente
2
Después de horas de búsqueda, esta es la única respuesta que encontró una solución a mi problema. +1
Super_Simon
9

Extendí la gran respuesta de David West para que pueda ingresar una cadena y decirle todas las subcadenas que le gustaría envalentonar:

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
}

Y luego llámalo así:

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!)

Esto animará todas las subcadenas que desea en negrita en su cadena dada

Jeremy Bader
fuente
¿Es posible tener la misma palabra en negrita en dos lugares diferentes? EJ: "Vuelve a consultar en 30 días para encontrar 30 amigos". ¿Cómo se ponen ambos "30" en negrita? Gracias por adelantado.
Dian
8

Esta es la mejor forma que se me ha ocurrido. Agregue una función que pueda llamar desde cualquier lugar y agréguela a un archivo sin una clase como Constants.swift y luego puede envalentonar palabras dentro de cualquier cadena, en numerosas ocasiones llamando solo UNA LÍNEA de código:

Para ir en un archivo 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
}

Entonces puede simplemente llamar a esta línea de código para cualquier 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)
David West
fuente
8

Sobre la base de las excelentes respuestas de Jeremy Bader y David West, una extensión de 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
    }
}

Uso:

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)
Daniel McLean
fuente
5

uso....

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

dos centavos...

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)
    }
}
Samuel
fuente
1
iOS 11 o superior (debido al uso de UIFont.Weight).
Andrea Leganza
4

Aceptando como válida la respuesta de Prajeet Shrestha en este hilo, me gustaría extender su solución usando la Etiqueta si se conoce y los rasgos de la fuente.

Rápido 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
    }
}
JSR - Silicornio
fuente
4

Swift 4 y superior

Para Swift 4 y superior, esa es una buena forma:

    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

En la etiqueta, el texto se ve así: "Hola Juan "

Jonas Deichelmann
fuente
3

Manera súper fácil de hacer esto.

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

Para obtener más detalles, haga clic aquí: https://github.com/iOSTechHub/AttributedString

Ashish Chauhan
fuente
¿Qué tal semi negrita?
Houman
Esta debería ser la respuesta aceptada. @Houman usa la biblioteca de arriba y usa el applymétodo con la fuente que quieras
Zack Shapiro
2

Esto podria ser util

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
}
Martín Jacob
fuente
2

Swift 3.0

Convierta html en cadena y cambie la fuente según sus requisitos.

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)!
}
Mitul Marsoniya
fuente
Debe convertir su cadena en datos usando utf8. Tenga en cuenta que los datos se ajustan a la recopilación en Swift 3, por lo que puede inicializar los datos con la vista de recopilación de su cadena utf8 Data("I'm a normal text and <b>this is my bold part . </b>And I'm again in the normal text".utf8)y establecer la codificación de caracteres en las opciones[NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue]
Leo Dabus
0

Simplemente use un código como este:

 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
Michał Ziobro
fuente
0

dos líneas en 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)
Antzi
fuente
0

Uso de Swift 5.1 enNSAttributedString.Key lugar deNSAttributedStringKey

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
Yodagama
fuente
0

Para -> Buscar televisión por tamaño

Unidireccional usando NString y su rango

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

otro sin usar NString y su rango

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

Vinoth Anandan
fuente
-1

Mejorando la respuesta de Prajeet Shrestha: -

Puede hacer una extensión genérica para NSMutableAttributedString que involucra menos código. En este caso, he optado por utilizar la fuente del sistema, pero podría adaptarla para poder ingresar el nombre de la fuente como parámetro.

    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
        }
    }
Eduardo
fuente
-1

Puede hacer esto usando el método personalizado simple escrito a continuación. Debe dar una cadena completa en el primer parámetro y el texto en negrita en el segundo parámetro. Espero que esto ayude.

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
    }

uso: initalString = Soy un niño

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

cadena resultante = soy un niño

Muhammad Haroon Iqbal
fuente