Muy buenas, les saluda Miguel y en esta ocasión les traigo este nuevo post.
El DSL
declarativo NSAttributedString
del marco de Gaudí
Uno de los mayores desafíos al usar NSAttributedString
es mantener el código ordenado y legible. Analicemos un caso simple para entender exactamente a qué me refiero:
let hello = NSAttributedString(string: "Hello, ", attributes: [ .foregroundColor: UIColor.red ]) let swift = NSAttributedString(string: "Swift", attributes: [ .foregroundColor: UIColor.orange, .font: UIFont.systemFont(ofSize: 18) ]) let final = NSMutableAttributedString(attributedString: hello) final.append(swift)
Esta es la cantidad mínima de código necesaria para lograr la cadena atribuida «Hola Swift» que podemos ver en la imagen. ¿Qué está mal con eso?
- No hay ayuda del
IDE
para componer la claveNSAttributedString.Key
del atributo. Desafortunadamente, elIDE
, por alguna razón, no ofrece un autocompletado para esos. - Seguridad de tipo cero para los valores: Los valores de los atributos son de tipo
Any
. - Código detallado y repetitivo: necesitamos crear una cadena con atributos para cada parte de la cadena con diferentes atributos y luego tenemos que componer estas dos cadenas con atributos usando un
NSMutableAttributedString
.
Ya hemos visto el poder de Gaudi con múltiples temas de aplicación y modo oscuro, en esta ocasión analizaremos su solución para formatear cadenas fácilmente con NSAttributedString
.
Gaudí hace un buen uso de la función Swift 5.1 constructor de funciones y lo combina con la forma declarativa que tiene para declarar colores y estilos de fuente.
Este marco, en lo que respecta a NSAttributedString
, promete ofrecer una manera fácil y segura de definir diferentes colores, fuentes y estilos. El ejemplo anterior con Gaudi DSL se vería así:
let final = NSAttributedString "Hello, ".foreground(color: .red) "Swift".foreground(color: .orange) .font(.systemFont(ofSize: 18))
Eso es todo … Gaudi permite una forma muy concisa, segura de escribir y no verbosa de componer NSAttributedStrings
comenzando desde desnudo tipos String
.
Obviamente, los colores semánticos y los estilos de fuente también son compatibles con DSL
y se pueden usar así:
let final = NSAttributedString "Hello, ".foreground(semanticColor: .label(.primary)) "Swift".foreground(semanticColor: .label(.secondary)) .font(forStyle: .title(attribute: .regular))
El DSL
también admite declaraciones if
y if-else
:
let final = NSAttributedString "Hello, ".foreground(semanticColor: .label(.primary)) if swiftGreeting "Swift".foreground(semanticColor: .label(.secondary)) .font(forStyle: .title(attribute: .regular)) else "World".foreground(semanticColor: .label(.tertiary)) .font(forStyle: .subhead(attribute: .bold))
Existente las instancias NSAttriutedString
también se pueden combinar y modificar utilizando este enfoque:
let hello = NSAttributedString(string: "Hello, ", attributes: [ .foregroundColor: UIColor.red ])let final = NSAttributedString hello.foreground(semanticColor: .label(.primary)) // replace color for "Hello, " "Swift".foreground(semanticColor: .label(.secondary)) .font(forStyle: .title(attribute: .regular))
Gaudi ofrece las mismas API declarativas también si todo lo que necesita es NSAttributedString
atributos que se aplicarán posteriormente a un ejemplo NSAttributedString
. Por ejemplo, estos atributos
let attributes = [ NSAttributedString.Key.foregroundColor: UIColor.green, .backgroundColor: UIColor.red ]
Con Gaudi se convierte en esto:
let attributes = StringAttributes foregroundAttribute(withColor: .green) backgroundAttribute(withColor: .red) .attributes // will be of type [NSAttributedString.Key : Any]
También, StringAttributes
DSL admite declaraciones if
y if-else
.
Obviamente, estas API también se pueden utilizar sin DSL
, por ejemplo:
let hello = "Hello, Swift" .foreground(semanticColor: .label(.primary)) .font(forStyle: .title(attribute: .regular))// Hello is of type NSAttributedString
Te recuerdo que Gaudi es completamente de código abierto, así que si tienes curiosidad sobre los detalles de implementación para lograr estos resultados, no dudes en continuar repositorio de GitHub del proyecto.
En particular, animo a leer las pruebas unitarias extensas para descubrir todas las funcionalidades de este marco. Puedes adoptar a Gaudi usando swiftPM y CocoaPods.
Espero que hayas aprendido algo nuevo.
Añadir comentario