La edición de texto enriquecido ha sido durante años uno de los componentes más complejos de implementar en aplicaciones nativas. Con los nuevos lanzamientos de iOS 26 y macOS 26, Apple ha mejorado considerablemente las herramientas disponibles para trabajar con texto enriquecido en SwiftUI. En este artículo exploraremos cómo construir interfaces modernas de edición de texto enriquecido usando TextView y AttributedString en SwiftUI, aprovechando las últimas APIs y capacidades de Xcode.
Este tutorial está pensado tanto para desarrolladores intermedios como avanzados que quieran dominar la manipulación de texto enriquecido fácilmente en sus apps.
🧠 ¿Qué es Texto Enriquecido?
El texto enriquecido (o rich text) permite aplicar atributos visuales a partes de un texto: negrita, cursiva, colores, tamaños de fuente, enlaces, listas, y más. A diferencia del texto plano (String), el texto enriquecido combina contenido con estilo, lo que exige una representación más sofisticada y controlada.
En SwiftUI moderno, esto se logra principalmente con:
- AttributedString: Tipo estructurado de Swift para contenido estilizado.
- TextView: Vista que permite edición interactiva del texto enriquecido (especialmente útil para entrada de usuario).
📦 Requisitos Previos
Antes de comenzar, asegúrate de tener:
✅ Xcode 18 o superior
✅ iOS 26 SDK / macOS 26 SDK
✅ Conocimientos básicos de Swift y SwiftUI
📘 Introducción a AttributedString
AttributedString es una estructura poderosa en Swift que representa texto con atributos. A diferencia de NSString / NSAttributedString, AttributedString es seguro para el compilador y está totalmente integrado con Swift.
Ejemplo básico:
import SwiftUI
let attributed = try! AttributedString(
markdown: "**Hola**, *mundo*!",
options: .init(interpretedSyntax: .inlineOnlyPreservingWhitespace)
)Este fragmento convierte Markdown en texto enriquecido con atributos de negrita y cursiva.
🛠 Paso 1: Configurando un Proyecto en Xcode
- Abre Xcode 18
- Crea un nuevo proyecto SwiftUI
- Selecciona iOS 26 / macOS 26 como destino
- Crea un archivo Swift llamado
RichTextEditor.swift
🧩 Paso 2: Añadir un TextView para Edición de Texto Enriquecido
SwiftUI 6 en iOS 26 trae soporte mejorado para TextView, una vista integrada que permite editar texto enriquecido.
Aquí tienes una configuración básica:
import SwiftUI
struct RichTextEditor: View {
@State private var attributedText = AttributedString("")
var body: some View {
TextView(
text: $attributedText,
isRichText: true
)
.padding()
.border(.gray, width: 1)
}
}Importante: TextView ahora acepta binding directo a AttributedString, ¡lo que hace que editar texto enriquecido sea tan simple como trabajar con String!
🛡 Propiedad isRichText
La bandera isRichText le indica al sistema que active controles y capacidades de formato enriquecido (negrita, listas, colores, etc.).
🖌 Paso 3: Estilos y Atributos Básicos
Veamos cómo aplicar atributos al texto programáticamente.
Negrita y Cursiva
var bold = AttributedString("Negrita")
bold.font = .boldSystemFont(ofSize: 18)
var italic = AttributedString(" Cursiva")
italic.font = .italicSystemFont(ofSize: 18)Puedes combinar múltiples AttributedString y componer textos ricos complejos.
🔗 Paso 4: Insertar Enlaces
var linkText = AttributedString("Visita OpenAI")
linkText.link = URL(string: "https://openai.com")Los enlaces son interactivos en TextView automáticamente (clicables o táctiles según plataforma).
🎯 Paso 5: Aplicar Atributos desde la UI
Aunque puedes construir AttributedString desde código, lo más habitual en un editor es que el usuario seleccione texto y aplique formato.
Interfaz de Formato
struct FormatToolbar: View {
@Binding var text: AttributedString
var body: some View {
HStack {
Button("B") { toggleBold() }
Button("I") { toggleItalic() }
Button("Color") { applyColor() }
}
}
func toggleBold() {
if let range = text.runs.first?.range {
text[range].font = .boldSystemFont(ofSize: 18)
}
}
func toggleItalic() {
if let range = text.runs.first?.range {
text[range].font = .italicSystemFont(ofSize: 18)
}
}
func applyColor() {
if let range = text.runs.first?.range {
text[range].foregroundColor = .blue
}
}
}🔍 ¿Qué está pasando aquí?
- Extraemos un range de texto.
- Aplicamos atributos como
.fonto.foregroundColor.
🎨 Paso 6: Añadir Color al Texto
Más código para aplicar color al texto seleccionado:
func applyColor(_ color: Color) {
if let selectedRange = text.runs.first?.range {
text[selectedRange].foregroundColor = UIColor(color)
}
}Puedes usar un selector de color para permitir múltiples opciones.
🧪 Ejemplo Completo Integrado
Aquí tienes un ejemplo real que combina TextView con una barra de herramientas de formato:
import SwiftUI
struct RichTextEditorView: View {
@State private var attributedText = AttributedString("Escribe aquí…")
var body: some View {
VStack {
FormatToolbar(text: $attributedText)
.padding()
TextView(text: $attributedText, isRichText: true)
.padding()
.border(.secondary, width: 1)
}
.padding()
}
}Y el toolbar:
struct FormatToolbar: View {
@Binding var text: AttributedString
var body: some View {
HStack {
Button("B") { applyStyle(.bold) }
Button("I") { applyStyle(.italic) }
Button("U") { applyStyle(.underline) }
}
}
enum Style { case bold, italic, underline }
func applyStyle(_ style: Style) {
guard let range = text.runs.first?.range else { return }
switch style {
case .bold:
text[range].font = .boldSystemFont(ofSize: 18)
case .italic:
text[range].font = .italicSystemFont(ofSize: 18)
case .underline:
text[range].underlineStyle = .single
}
}
}Detalles Avanzados de AttributedString
✔️ Atributos disponibles
AttributedString puede tener:
.font.foregroundColor.backgroundColor.underlineStyle.strikethroughStyle.link.baselineOffset
…y muchos más.
✔️ Rango inteligente
AttributedString organiza texto en runs, es decir, segmentos con atributos homogéneos. Puedes manipular rangos fácilmente con:
for run in attributedText.runs {
print(run.range, run.attributes)
}🧠 Integración con Markdown
iOS 26 / macOS 26 trae soporte nativo para inicializar AttributedString vía Markdown:
let mdText = try AttributedString(
markdown: "**Negrita** y _Cursiva_",
options: .init(interpretedSyntax: .full)
)Esto significa que puedes permitir que los usuarios ingrese Markdown y renderizarlo automáticamente como texto enriquecido.
Ten en cuenta que algunas APIs nuevas solo funcionan en las versiones más recientes de SDK.
🧪 Testeo en Simulador y Dispositivo
- Ejecuta en simulador iPhone con iOS 26
- Prueba selección de texto y aplicación de estilos
- Testea que enlaces sean clicables
- Ajusta colores y fuentes según el tema de tu app
💡 Mejores Prácticas y Consejos
🔹 Usa AttributedString siempre que puedas
Evita mezclar con NSAttributedString a menos que necesites compatibilidad con APIs antiguas.
🔹 Modulariza las herramientas de formato
Crea un toolbar reutilizable para aplicar atributos.
🔹 Control de selección
Asegúrate de manejar selección de rango con cuidado para no sobrescribir estilos no deseados.
🔹 Persistencia
Guarda el contenido enriquecido como Markdown o RTF para conservar estilos entre sesiones.
🚀 Expandiendo tu Editor
Aquí algunas ideas avanzadas que puedes implementar:
📌 Soporte de Listas
Permite a los usuarios crear listas con viñetas o numeradas.
📌 Insertar Imágenes
Permite dropear o seleccionar imágenes dentro del texto enriquecido.
📌 Historial de Deshacer/Rehacer
Implementa undo/redo para mejorar la experiencia de edición.
✅ Conclusión
Gracias a las mejoras en SwiftUI con iOS 26 y macOS 26, crear un editor de texto enriquecido nunca ha sido tan accesible. Con TextView y AttributedString, puedes:
✔️ Crear interfaces de edición modernas
✔️ Manipular atributos fácilmente
✔️ Integrar Markdown de forma nativa
✔️ Personalizar colores, estilos y enlaces
Este tutorial te ha dado una base sólida para empezar. A partir de aquí, puedes expandir tu editor con características más avanzadas como estilos personalizados, soporte para imágenes, HTML, o integración con servicios de sincronización en nube.
Si tienes cualquier duda sobre este artículo, contacta conmigo y estaré encantado de ayudarte 🙂. Puedes contactar conmigo en mi perfil de X o en mi perfil de Instagram









