Saltar al contenido

Forme parte de un UILabel bold en Swift

Estate atento ya que en esta sección encontrarás la contestación que buscas.

Solución:

Querrás usar attributedString que le permite diseñar partes de un string etc. Esto se puede hacer así teniendo dos estilos, uno normal, otro en negrita, y luego uniéndolos:

let boldText = "Filter:"
let attrs = [NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 15)]
let attributedString = NSMutableAttributedString(string:boldText, attributes:attrs)

let normalText = "Hi am normal"
let normalString = NSMutableAttributedString(string:normalText)

attributedString.append(normalString)

Cuando quieras asignarlo a una etiqueta:

label.attributedText = attributedString

Puede utilizar NSMutableAttributedString y NSAttributedString para crear string. La siguiente función hace que boldString dado en negrita en dado string.

Swift 3

func attributedText(withString string: String, boldString: String, font: UIFont) -> NSAttributedString 
    let attributedString = NSMutableAttributedString(string: string,
                                                     attributes: [NSFontAttributeName: font])
    let boldFontAttribute: [String: Any] = [NSFontAttributeName: UIFont.boldSystemFont(ofSize: font.pointSize)]
    let range = (string as NSString).range(of: boldString)
    attributedString.addAttributes(boldFontAttribute, range: range)
    return attributedString

Uso de ejemplo

authorLabel.attributedText = attributedText(withString: String(format: "Author : %@", user.name), boldString: "Author", font: authorLabel.font)

Rápido 4

func attributedText(withString string: String, boldString: String, font: UIFont) -> NSAttributedString 
    let attributedString = NSMutableAttributedString(string: string,
                                                     attributes: [NSAttributedStringKey.font: font])
    let boldFontAttribute: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: font.pointSize)]
    let range = (string as NSString).range(of: boldString)
    attributedString.addAttributes(boldFontAttribute, range: range)
    return attributedString

Swift 4.2 y 5

func attributedText(withString string: String, boldString: String, font: UIFont) -> NSAttributedString 
    let attributedString = NSMutableAttributedString(string: string,
                                                 attributes: [NSAttributedString.Key.font: font])
    let boldFontAttribute: [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: font.pointSize)]
    let range = (string as NSString).range(of: boldString)
    attributedString.addAttributes(boldFontAttribute, range: range)
    return attributedString

Resultado:

ingrese la descripción de la imagen aquí

Swift 4.2 y 5.0:

Primero, creamos un protocolo que UILabel, UITextField y UITextView puede adoptar.

public protocol ChangableFont: AnyObject 
    var rangedAttributes: [RangedAttributes]  get 
    func getText() -> String?
    func set(text: String?)
    func getAttributedText() -> NSAttributedString?
    func set(attributedText: NSAttributedString?)
    func getFont() -> UIFont?
    func changeFont(ofText text: String, with font: UIFont)
    func changeFont(inRange range: NSRange, with font: UIFont)
    func changeTextColor(ofText text: String, with color: UIColor)
    func changeTextColor(inRange range: NSRange, with color: UIColor)
    func resetFontChanges()

Queremos poder agregar múltiples cambios a nuestro texto, por lo tanto creamos el rangedAttributes propiedad. Es una estructura personalizada que se mantiene attributes y el rango en el que se aplican.

public struct RangedAttributes 

    public let attributes: [NSAttributedString.Key: Any]
    public let range: NSRange

    public init(_ attributes: [NSAttributedString.Key: Any], inRange range: NSRange) 
        self.attributes = attributes
        self.range = range
    

Otro problema es que UILabel su font la propiedad es fuerte y UITextField su font la propiedad es débil / opcional. Para que ambos funcionen con nuestro ChangableFont protocolo incluimos el getFont() -> UIFont? método. Esto también cuenta para UITextView su text y attributedText propiedades. Es por eso que también implementamos los métodos getter y setter para ellos.

extension UILabel: ChangableFont 

    public func getText() -> String? 
        return text
    

    public func set(text: String?) 
        self.text = text
    

    public func getAttributedText() -> NSAttributedString? 
        return attributedText
    

    public func set(attributedText: NSAttributedString?) 
        self.attributedText = attributedText
    

    public func getFont() -> UIFont? 
        return font
    


extension UITextField: ChangableFont 

    public func getText() -> String? 
        return text
    

    public func set(text: String?) 
        self.text = text
    

    public func getAttributedText() -> NSAttributedString? 
        return attributedText
    

    public func set(attributedText: NSAttributedString?) 
        self.attributedText = attributedText
    

    public func getFont() -> UIFont? 
        return font
    


extension UITextView: ChangableFont 

    public func getText() -> String? 
        return text
    

    public func set(text: String?) 
        self.text = text
    

    public func getAttributedText() -> NSAttributedString? 
        return attributedText
    

    public func set(attributedText: NSAttributedString?) 
        self.attributedText = attributedText
    

    public func getFont() -> UIFont? 
        return font
    

Ahora podemos seguir adelante y crear la implementación predeterminada para UILabel, UITextField y UITextView ampliando nuestro protocolo.

public extension ChangableFont 

    var rangedAttributes: [RangedAttributes] 
        guard let attributedText = getAttributedText() else 
            return []
        
        var rangedAttributes: [RangedAttributes] = []
        let fullRange = NSRange(
            location: 0,
            length: attributedText.string.count
        )
        attributedText.enumerateAttributes(
            in: fullRange,
            options: []
        )  (attributes, range, stop) in
            guard range != fullRange, !attributes.isEmpty else  return 
            rangedAttributes.append(RangedAttributes(attributes, inRange: range))
        
        return rangedAttributes
    

    func changeFont(ofText text: String, with font: UIFont) 
        guard let range = (self.getAttributedText()?.string ?? self.getText())?.range(ofText: text) else  return 
        changeFont(inRange: range, with: font)
    

    func changeFont(inRange range: NSRange, with font: UIFont) 
        add(attributes: [.font: font], inRange: range)
    

    func changeTextColor(ofText text: String, with color: UIColor) 
        guard let range = (self.getAttributedText()?.string ?? self.getText())?.range(ofText: text) else  return 
        changeTextColor(inRange: range, with: color)
    

    func changeTextColor(inRange range: NSRange, with color: UIColor) 
        add(attributes: [.foregroundColor: color], inRange: range)
    

    private func add(attributes: [NSAttributedString.Key: Any], inRange range: NSRange) 
        guard !attributes.isEmpty else  return 

        var rangedAttributes: [RangedAttributes] = self.rangedAttributes

        var attributedString: NSMutableAttributedString

        if let attributedText = getAttributedText() 
            attributedString = NSMutableAttributedString(attributedString: attributedText)
         else if let text = getText() 
            attributedString = NSMutableAttributedString(string: text)
         else 
            return
        

        rangedAttributes.append(RangedAttributes(attributes, inRange: range))

        rangedAttributes.forEach  (rangedAttributes) in
            attributedString.addAttributes(
                rangedAttributes.attributes,
                range: rangedAttributes.range
            )
        

        set(attributedText: attributedString)
    

    func resetFontChanges() 
        guard let text = getText() else  return 
        set(attributedText: NSMutableAttributedString(string: text))
    

Con la implementación predeterminada, utilizo un pequeño método auxiliar para obtener el NSRange de un substring.

public extension String 

    func range(ofText text: String) -> NSRange 
        let fullText = self
        let range = (fullText as NSString).range(of: text)
        return range
    

¡Terminamos! Ahora puede cambiar partes del texto, su fuente y color de texto.

titleLabel.text = "Welcome"
titleLabel.font = UIFont.systemFont(ofSize: 70, weight: .bold)
titleLabel.textColor = UIColor.black
titleLabel.changeFont(ofText: "lc", with: UIFont.systemFont(ofSize: 60, weight: .light))
titleLabel.changeTextColor(ofText: "el", with: UIColor.blue)
titleLabel.changeTextColor(ofText: "co", with: UIColor.red)
titleLabel.changeTextColor(ofText: "m", with: UIColor.green)

Nos puedes añadir valor a nuestra información añadiendo tu veteranía en las referencias.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *