Tutoriales de SwiftUI y Swift para iOS Developers - PROGRAMACIONSWIFT.COM

Cómo crear un editor de texto enriquecido en SwiftUI

Tutorial completo paso a paso en Xcode

Introducción

Los editores de texto enriquecido (Rich Text Editors) son una pieza clave en muchas aplicaciones modernas: notas, correo electrónico, mensajería, blogs, apps de productividad y más. Permiten aplicar estilos como negrita, cursiva, subrayado, colores, tamaños de letra, listas y enlaces, todo mientras el usuario escribe.

Históricamente, en iOS, crear un editor de texto enriquecido era complicado y requería UIKit (UITextView) y NSAttributedString. Con la evolución de SwiftUI, especialmente de cara a iOS 26, Apple ha mejorado notablemente la interoperabilidad con texto enriquecido, haciendo posible construir editores potentes sin abandonar el paradigma declarativo.

En este tutorial aprenderás:

  • Qué es un Rich Text Editor y cómo funciona internamente
  • Cómo manejar texto enriquecido con AttributedString
  • Cómo integrar un editor editable en SwiftUI
  • Cómo crear una barra de herramientas (bold, italic, underline, color)
  • Cómo sincronizar estado, selección y formato
  • Buenas prácticas de arquitectura en SwiftUI

Al final tendrás un editor de texto enriquecido funcional, extensible y listo para producción.


Requisitos previos

Antes de comenzar, asegúrate de contar con:

  • Xcode compatible con iOS 26
  • Conocimientos básicos de Swift y SwiftUI
  • Familiaridad con @State@Binding y ObservableObject
  • Un Mac con macOS actualizado

1. ¿Qué es un Rich Text Editor en iOS?

Un Rich Text Editor es un componente que permite editar texto junto con información de formato. En iOS, este formato se representa mediante atributos asociados a rangos de texto.

Ejemplos de atributos:

  • Fuente (font)
  • Color (foregroundColor)
  • Estilo (bold, italic)
  • Subrayado
  • Enlaces
  • Alineación

En Swift moderno, Apple promueve el uso de:

AttributedString

en lugar de NSAttributedString, ya que es:

  • Más seguro
  • Más expresivo
  • Compatible con SwiftUI

2. Arquitectura del editor

Nuestro editor tendrá tres capas principales:

  1. Modelo de texto
    Usa AttributedString como fuente de verdad.
  2. Vista de edición
    Un componente editable en SwiftUI que renderiza y permite modificar el texto.
  3. Barra de herramientas
    Botones para aplicar formato al texto seleccionado.

Separar estas capas hará que el código sea más limpio y fácil de escalar.


3. Creando el proyecto en Xcode

  1. Abre Xcode
  2. Selecciona Create a new Xcode project
  3. Elige App
  4. Configura:
    • Interface: SwiftUI
    • Language: Swift
    • Target: iOS 26

Nombra el proyecto, por ejemplo:

RichTextEditorSwiftUI


4. El modelo de datos: AttributedString

Comenzamos creando un modelo observable que contendrá el texto:

import SwiftUI

class RichTextViewModel: ObservableObject {
    @Published var text: AttributedString = AttributedString("Escribe aquí tu texto...")
}

Este será el estado central del editor.


5. Mostrando texto enriquecido en SwiftUI

SwiftUI permite mostrar AttributedString directamente:

Text(viewModel.text)

Pero Text no es editable. Para editar texto enriquecido necesitamos un componente especial.


6. Usando TextEditor con AttributedString

En iOS 26, TextEditor soporta directamente AttributedString:

struct RichTextEditorView: View {
    @StateObject private var viewModel = RichTextViewModel()

    var body: some View {
        TextEditor(text: $viewModel.text)
            .padding()
    }
}

Con esto ya tienes un editor de texto enriquecido básico.


7. Capturando la selección de texto

Para aplicar estilos necesitamos saber qué parte del texto está seleccionada.

@Published var selectedRange: Range<AttributedString.Index>?

En iOS 26, TextEditor expone eventos de selección mediante modificadores:

.onSelectionChange { range in
    viewModel.selectedRange = range
}

8. Aplicando formato: Negrita

Creamos una función para aplicar negrita al texto seleccionado:

func toggleBold() {
    guard let range = selectedRange else { return }

    let isBold = text[range].font?.weight == .bold

    text[range].font = .system(
        size: 16,
        weight: isBold ? .regular : .bold
    )
}

Este enfoque modifica solo el rango seleccionado.


9. Barra de herramientas de formato

Creamos una barra de botones:

struct FormatToolbar: View {
    @ObservedObject var viewModel: RichTextViewModel

    var body: some View {
        HStack {
            Button("B") {
                viewModel.toggleBold()
            }
            .font(.system(size: 18, weight: .bold))

            Button("I") {
                viewModel.toggleItalic()
            }
            .italic()

            Button("U") {
                viewModel.toggleUnderline()
            }
        }
        .padding()
        .background(.ultraThinMaterial)
    }
}

10. Cursiva y subrayado

Implementamos las funciones restantes:

func toggleItalic() {
    guard let range = selectedRange else { return }
    text[range].font = .system(size: 16).italic()
}

func toggleUnderline() {
    guard let range = selectedRange else { return }
    text[range].underlineStyle =
        text[range].underlineStyle == nil ? .single : nil
}

11. Color de texto

Añadimos soporte para color:

func setTextColor(_ color: Color) {
    guard let range = selectedRange else { return }
    text[range].foregroundColor = color
}

Y botones de color:

Button {
    viewModel.setTextColor(.red)
} label: {
    Circle().fill(Color.red).frame(width: 20)
}

12. Integrando todo en la vista principal

struct ContentView: View {
    @StateObject private var viewModel = RichTextViewModel()

    var body: some View {
        VStack(spacing: 0) {
            FormatToolbar(viewModel: viewModel)

            TextEditor(text: $viewModel.text)
                .padding()
        }
    }
}

13. Guardar y cargar texto enriquecido

Puedes serializar el texto a Data:

let data = try? viewModel.text.data(using: .rtf)

Y restaurarlo:

if let data {
    viewModel.text = try AttributedString(data: data)
}

Ideal para Core Data, archivos o iCloud.


14. Buenas prácticas

✔ Usa AttributedString como fuente única de verdad
✔ No mezcles UIKit innecesariamente
✔ Centraliza la lógica de formato en el ViewModel
✔ Mantén la UI declarativa
✔ Piensa en extensibilidad (listas, encabezados, enlaces)


15. Ideas para mejorar el editor

  • Listas numeradas y con viñetas
  • Encabezados (H1, H2, H3)
  • Soporte para enlaces
  • Undo / Redo personalizado
  • Exportación a Markdown o HTML
  • Soporte para teclado externo

Conclusión

Crear un Rich Text Editor en SwiftUI para iOS 26 ya no es una tarea compleja ni reservada a UIKit. Gracias a AttributedString, mejoras en TextEditor y el modelo declarativo, podemos construir editores potentes, elegantes y mantenibles.

Este tutorial te proporciona una base sólida y profesional para integrar edición avanzada de texto en tus aplicaciones iOS modernas. A partir de aquí, el límite lo pone tu imaginación (y un poco de diseño UX).

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

Visited 1 times, 1 visit(s) today
Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Article

Liquid Glass en botones en SwiftUI

Next Article

@ViewBuilder en SwiftUI

Related Posts