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:
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.