Contenido del curso
Estructura de un Proyecto con MVVM
Operaciones CRUD en un proyecto con MVVM
- 11

Función addTodo con Core Data en SwiftUI
19:47 min - 12

Funcionalidades básicas para gestionar tareas en SwiftUI
14:30 min - 13

Listado y detalle de notas en SwiftUI
Viendo ahora - 14

Editar todos con SwiftUI y Core Data
13:41 min - 15

Archivar tareas en SwiftUI con Core Data
15:28 min - 16

Cómo desarchivar tareas con unarchiveTodo
03:25 min - 17

Eliminar un to do definitivamente con Core Data
04:15 min - 18

Marcar tareas completadas en SwiftUI
20:50 min - 19

Creación de Vistas Amigables en SwiftUI para Aplicaciones de Tareas
19:52 min
Clean Architecture
- 20

Qué es Clean Architecture y por qué supera a MVVM
05:52 min - 21

Estructura y Ventajas de la Clean Architecture
03:47 min - 22

Estructura de proyecto iOS con Clean Architecture
06:01 min - 23

Mapeo de JSON a structs Swift con Codable
09:10 min - 24

Capa de datos con Clean Architecture en Swift
30:54 min - 25

Casos de uso en la capa de dominio Swift
09:35 min - 26

Capa de presentación con MVVM en SwiftUI
15:37 min - 27

Navegación y detalle con Clean Architecture en SwiftUI
21:54 min
MVVM y Clean Architecture
Listado y detalle de notas en SwiftUI
Resumen
Cuando construyes una app de notas en SwiftUI, agregar tareas es solo la mitad del camino. La otra mitad consiste en listar las notas y mostrar su detalle de forma fluida, usando un patrón MVVM con environment object, filtros y vistas previas animadas. Aquí verás cómo conectar la vista con el view model, filtrar tareas no archivadas y mostrar un preview al tocar cada elemento.
Cómo conecto el view model con la vista de lista
Lo primero es darle a tu vista acceso al view model compartido. En el archivo ToDoList, declaras una referencia con la anotación @EnvironmentObject y creas una variable de tipo ToDoViewModel [00:13]. Esta anotación permite que la vista lea los datos sin tener que instanciar manualmente el modelo.
Junto con esa referencia, necesitas dos variables de estado para controlar la interfaz:
showSheet: indica si está abierta la pantalla para crear una nueva nota.toDoToPreview: de tipoToDoEntity, indica si hay una nota en vista previa.
La segunda se declara con @State private var y arranca vacía [00:48]. Su función es disparar la aparición del detalle cuando el usuario toca una tarjeta.
¿Qué hace @EnvironmentObject en SwiftUI? Inyecta una instancia compartida del view model en cualquier vista del árbol, sin pasarla como parámetro. Es ideal para datos globales como una lista de tareas.
Cómo filtro las tareas no archivadas con una variable computada
Las notas se muestran en dos pantallas distintas, así que necesitas separar las archivadas de las que siguen activas. Para eso creas una variable privada llamada unarchivedTodos de tipo [ToDoEntity] [01:33].
La lógica usa el método filter sobre la propiedad pública todos del view model:
swift private var unarchivedTodos: [ToDoEntity] { viewModel.todos.filter { !$0.isArchived } }
El filter itera toda la colección desde la posición cero y devuelve solo los elementos donde isArchived sea falso [02:30]. Así obtienes una lista limpia para la pantalla principal, sin importar si la tarea está terminada o pendiente.
Cómo muestro las notas en una grilla con LazyVGrid
Dentro del ScrollView validas primero que existan elementos para mostrar. Usas if !unarchivedTodos.isEmpty y, si la condición se cumple, renderizas un LazyVGrid [03:25].
Este componente recibe varios parámetros clave:
columns: una variable previa con dos columnas tipo grid.spacing: separación de 8 puntos entre items.padding(.horizontal): para que no se peguen a los bordes.
La estructura queda lista para recibir las tarjetas. Para insertar cada elemento, usas un ForEach que itera sobre unarchivedTodos y, por cada todo, instancia un ToDoItemView enviando el parámetro toDo [05:50].
Cómo diseño cada tarjeta en ToDoItemView
En ToDoItemView declaras de nuevo el @EnvironmentObject y una variable pública let toDo: ToDoEntity. Antes de pintar el VStack, validas que el identificador no esté vacío con un if; en el else devuelves EmptyView() para evitar errores visuales [04:35].
Dentro de la tarjeta accedes a toDo.date para mostrar la fecha y, debajo, agregas una validación if let description = toDo.notes para mostrar la descripción solo cuando exista. El texto usa modificadores como .font(.caption), .fontWeight(.light) y .lineLimit(3) [06:50].
¿Para qué sirve LazyVGrid frente a un VStack? Renderiza los elementos solo cuando entran en pantalla, lo que mejora el rendimiento en listas largas. Además permite distribuir tarjetas en varias columnas con muy poca configuración.
Cómo abro el detalle de una nota con onTapGesture y overlay
Para que cada tarjeta sea interactiva, agregas un onTapGesture dentro del ForEach que asigna la nota tocada a toDoToPreview [07:55]. Ese cambio dispara la aparición de la vista previa.
La magia ocurre en la sección overlay del ZStack. Allí ya existe un if que muestra la pantalla de creación cuando showSheet es verdadero. Agregas un else if que valida toDoToPreview != nil y, si es así, instancia ToDoPreviewView pasándole el binding $toDoToPreview [08:30].
Para que la aparición se sienta natural, añades una transición animada:
swift .transition(AnyTransition.opacity.animation(.easeIn))
También bloqueas la barra de navegación con navigationBarHidden evaluando si showSheet está activo o si toDoToPreview no está vacío [04:00].
Cómo construyo ToDoPreviewView con binding y validación
En ToDoPreviewView defines tres propiedades:
@EnvironmentObject private var viewModel: ToDoViewModel.@Binding public var toDo: ToDoEntity?para recibir la nota seleccionada.@State private var showedToDoCreationSheet: Bool = falsepara controlar la edición.
Dentro del body, envuelves el contenido en un ZStack y usas if let savedToDo = toDo para mostrar el detalle solo si llega una entidad válida [09:50]. En el else, devuelves una vista vacía.
Después accedes a savedToDo.title para el encabezado y, fuera del HStack, validas if let note = savedToDo.notes, !note.isEmpty para pintar la descripción con .multilineTextAlignment(.center) [11:00].
Cómo cierro la vista previa al tocar el fondo difuminado
Falta un detalle de usabilidad: si el usuario toca fuera de la tarjeta, la pantalla debe cerrarse. En la parte superior del ZStack hay un Rectangle que actúa como fondo difuminado. Le agregas una acción que asigna toDo = nil, lo que limpia el binding y oculta el preview automáticamente [11:50].
Con esto cierras el flujo completo: listas las notas no archivadas, las muestras en una grilla, abres el detalle con un tap y cierras la vista previa con otro toque. ¿Qué función agregarías después: archivar, editar o eliminar? Cuéntame en los comentarios cuál implementarías primero.