Colocando o texto em negrito usando a string atribuída rapidamente

100

Eu tenho uma corda assim

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

Agora substitua text1por outra string, digamos t 1. Consigo substituir o texto, mas não consigo colocá-lo em negrito. Quero colocar a nova string em negrito t 1, para que o resultado final seja:

@t 1 isso é bom @t 1

Como eu posso fazer isso?

Todos os exemplos que estou vendo estão em Objective-C, mas quero fazê-lo em Swift.

Desde já, obrigado.

user2413621
fonte
1
Você precisa decompor seu problema: Aprenda como colocar em "negrito": stackoverflow.com/questions/25199580/… Aprenda como substituir texto.
Larme de
1
Use esta biblioteca, é mesquinho e simples. github.com/iOSTechHub/AttributedString
Ashish Chauhan

Respostas:

237

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:

insira a descrição da imagem aqui

Esta é uma maneira simples de fazer uma combinação de textos em negrito e normais em um único rótulo, além de alguns outros métodos de bônus.

Extensão: 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
fonte
não é para o Swift 2?
Remy Boys
2
Uma pequena adição: func bold(_ text:String, _ size:CGFloat). Eu adicionei o tamanho ao negrito para que eu possa controlá-lo de fora. Além disso, eu perdi a AvenirNext-Mediumfonte nesta função, então levei alguns minutos para entender por que não consigo ver minha fonte. Atenção.
Gal de
você salvou meu dia, cara!
oskarko
Obrigado! Funcionou como charme :)
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 você quiser atribuí-lo a um rótulo:

yourLabel.attributedText = attributedString
Dejan Skledar
fonte
Resposta incrível! Obrigado!
hacker_1989
observação: appendAttributedString foi renomeado para .append ()
Andrea Leganza
28

editar / atualizar: Xcode 8.3.2 • Swift 3.1

Se você conhece HTML e CSS, pode usá-los para controlar facilmente o estilo da fonte, a cor e o tamanho da string atribuída da seguinte forma:

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
fonte
Estou tentando implementar isso no Swift 2 Xcode, mas a fonte não está sendo aplicada. Aqui está a corda: <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 for usar WebKit para analisar strings HTML em NSAttributedString, tome cuidado ao usá-lo em um thread de segundo plano ...
FouZ
Quais são os benefícios de usar essa abordagem em vez da resposta @prajeet?
Emre Önder
17

Se você estiver trabalhando com strings localizadas, pode não ser capaz de contar com a string em negrito sempre no final da frase. Se for esse o caso, o seguinte funciona bem:

por exemplo, a consulta "blá" não corresponde a nenhum item

/* 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
fonte
2
Depois de horas de procura, esta é a única resposta que encontrou uma solução para o meu problema. +1
Super_Simon
9

Eu estendi a ótima resposta de David West para que você possa inserir uma string e dizer a ela todas as substrings que gostaria de enfatizar:

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 então chame assim:

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

Isso irá enfatizar todas as substrings que você deseja colocar em negrito em sua determinada string

Jeremy Bader
fonte
É possível ter a mesma palavra em negrito em dois lugares diferentes? EX: "Verifique novamente em 30 dias para encontrar 30 amigos". Como você deixa ambos "30" em negrito? Desde já, obrigado.
Dia
8

Esta é a melhor maneira que eu inventei. Adicione uma função que você pode chamar de qualquer lugar e adicione-a a um arquivo sem uma classe como Constants.swift e então você pode enfatizar palavras em qualquer string, em várias ocasiões, chamando apenas UMA LINHA de código:

Para ir em um arquivo 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
}

Em seguida, você pode simplesmente chamar essa linha de código para qualquer 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
fonte
8

Com base nas excelentes respostas de Jeremy Bader e David West, uma extensão do 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
fonte
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")

dois 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
fonte
1
iOS 11 ou superior (devido ao uso de UIFont.Weight).
Andrea Leganza,
4

Aceitando como válida a resposta de Prajeet Shrestha neste tópico, gostaria de estender sua solução usando o Label se ele for conhecido e os traços da fonte.

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
    }
}
JSR - Silicornio
fonte
4

Swift 4 e superior

Para Swift 4 e superior, essa é uma boa maneira:

    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

No rótulo, o texto se parece com: "Oi John "

Jonas Deichelmann
fonte
3

Uma maneira super fácil de fazer isso.

    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 obter mais detalhes, clique aqui: https://github.com/iOSTechHub/AttributedString

Ashish Chauhan
fonte
Que tal semi-negrito?
Houman
Esta deve ser a resposta aceita. @Houman use a biblioteca acima e use o applymétodo com a fonte que você quiser
Zack Shapiro
2

Isso pode ser útil

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
}
Martin Jacob
fonte
2

Swift 3.0

Converta html em string e altere a fonte de acordo com suas necessidades.

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
fonte
Você deve converter sua string em dados usando utf8. Observe que os dados estão em conformidade com a coleta no Swift 3, portanto, você pode inicializar os dados com a visualização da coleção utf8 de sua string Data("I'm a normal text and <b>this is my bold part . </b>And I'm again in the normal text".utf8)e definir a codificação de caracteres nas opções[NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue]
Leo Dabus
0

Basta usar um 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
fonte
0

dois liner em 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
fonte
0

Swift 5.1 usa em NSAttributedString.Keyvez 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
fonte
0

Para -> Pesquisar televisão por tamanho

Unilateral usando NString e seu intervalo

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

outro sem usar NString e seu intervalo

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
fonte
-1

Melhorando a resposta de Prajeet Shrestha: -

Você pode fazer uma extensão genérica para NSMutableAttributedString que envolve menos código. Neste caso, optei por usar a fonte do sistema, mas você pode adaptá-la para inserir o nome da fonte como um 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
        }
    }
Edward
fonte
-1

Você pode fazer isso usando o método personalizado simples escrito abaixo. Você deve fornecer string inteira no primeiro parâmetro e o texto em negrito no segundo parâmetro. Espero que isso ajude.

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 = Eu sou um menino

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

string resultante = eu sou um menino

Muhammad Haroon Iqbal
fonte