Programación en Swift y SwiftUI para iOS Developers

200 preguntas de entrevistas iOS sobre SwiftUI

Si estás preparándote para una entrevista de desarrollador iOS o macOS hoy en día, SwiftUI ya no es opcional; es el estándar. Las empresas ya no preguntan solo “¿sabes usarlo?”, sino “¿entiendes cómo funciona su gestión de estado y renderizado?”.

Para ayudarte a dominar la entrevista técnica, he recopilado una colección masiva de preguntas. En esta primera parte de nuestra serie, cubrimos las 100 preguntas esenciales en formato “Ronda Relámpago”: preguntas directas con respuestas concisas para refrescar tu memoria rápidamente.


🟢 Nivel 1: Conceptos Fundamentales

Estas preguntas verifican si entiendes la filosofía detrás del framework.

  1. ¿Qué es SwiftUI? Es un framework declarativo de interfaz de usuario creado por Apple para construir UIs en todas sus plataformas (iOS, macOS, watchOS, tvOS) utilizando Swift.
  2. ¿Cuál es la diferencia principal entre SwiftUI y UIKit? SwiftUI es declarativo (describes qué quieres que haga la UI), mientras que UIKit es imperativo (describes cómo debe construirse y modificarse paso a paso).
  3. ¿Qué significa que SwiftUI es “Declarativo”? Significa que el código define el estado final de la interfaz y el sistema se encarga de renderizar los cambios cuando el estado varía, en lugar de gestionar las transiciones manualmente.
  4. ¿Por qué las Vistas (View) en SwiftUI son Structs y no Classes? Las estructuras son tipos de valor (value types), más ligeras y rápidas de crear. Esto permite a SwiftUI recrearlas miles de veces sin impacto en el rendimiento, facilitando el sistema de “diffing” para actualizar la pantalla.
  5. ¿Qué es el protocolo View? Es el protocolo base de SwiftUI. Cualquier cosa que se dibuje en pantalla debe conformarse a View y definir una propiedad body.
  6. ¿Qué tipo devuelve la propiedad body? Devuelve some View.
  7. ¿Qué significa some View (Opaque Return Type)? Indica que la propiedad devuelve algo que conforma el protocolo View, pero oculta el tipo concreto (que podría ser muy complejo, como VStack<TupleView<...>>) al compilador externo.
  8. ¿Qué es un Modifier? Es un método que crea una nueva vista aplicando un cambio a la vista original (ej. .padding().background()).
  9. ¿Importa el orden de los modificadores? Sí, absolutamente. .background(Color.red).padding() es diferente a .padding().background(Color.red).
  10. ¿Qué es el Canvas en Xcode? Es el área de previsualización interactiva que muestra los cambios de código SwiftUI en tiempo real sin necesidad de compilar toda la app.
  11. ¿Qué es PreviewProvider (o la macro #Preview)? Es el código que genera la vista previa en el Canvas. Desde Xcode 15, se usa la macro #Preview para simplificar la sintaxis.
  12. ¿SwiftUI soporta Auto Layout? No directamente. SwiftUI usa su propio sistema de layout basado en Stacks, Spacers y Alignment, aunque por debajo usa tecnologías similares al motor de layout.
  13. ¿Cómo se depura una vista en SwiftUI? Se puede usar Self._printChanges() dentro del cuerpo de la vista para ver qué causó el redibujado, o usar los View Debuggers de Xcode.
  14. ¿Cuál es el ciclo de vida básico de una vista? Inicialización -> onAppear -> Actualizaciones (por cambios de estado) -> onDisappear.
  15. ¿Qué es Group? Un contenedor que agrupa vistas sin aplicar ningún layout visual (no las apila), útil para superar el límite de 10 vistas por contenedor o aplicar modificadores a varias vistas a la vez.

🔵 Nivel 2: Gestión de Estado (El Core de SwiftUI)

Si fallas aquí, fallas la entrevista. Entender el flujo de datos es vital.

  1. ¿Qué es la “Source of Truth” (Fuente de la Verdad)? El concepto de que los datos deben existir en un único lugar y las vistas solo deben leer o reaccionar a esos datos, no duplicarlos.
  2. ¿Qué hace @State? Declara una propiedad mutable propiedad de la vista. Cuando cambia, SwiftUI redibuja la vista automáticamente. Se usa para estados locales simples (ej. un toggle).
  3. ¿Por qué @State debe declararse como private? Porque está diseñado para ser usado solo internamente por la vista que lo crea.
  4. ¿Qué es @Binding? Permite a una vista hija leer y escribir un valor propiedad de una vista padre sin poseer el dato. Es una referencia de lectura/escritura.
  5. ¿Cuál es la diferencia entre @ObservedObject y @StateObject? @StateObject asegura que el objeto se crea una sola vez y persiste aunque la vista se redibuje. @ObservedObject no garantiza la persistencia si la vista propietaria se destruye y recrea; se usa para objetos inyectados que ya existen.
  6. ¿Cuándo usarías @EnvironmentObject? Para datos que necesitan ser accesibles por muchas vistas en la jerarquía (como un perfil de usuario o configuración de tema) sin tener que pasarlos manualmente de padre a hijo (prop drilling).
  7. ¿Qué protocolo debe cumplir una clase para usar @Published? ObservableObject.
  8. ¿Qué hace la propiedad @Published? Notifica automáticamente a los observadores cuando el valor de la variable cambia, provocando actualizaciones en la UI.
  9. ¿Qué es @Environment? Permite leer valores del entorno del sistema, como el modo oscuro (.colorScheme), la clase de tamaño horizontal, o la configuración regional.
  10. ¿Qué es @AppStorage? Un property wrapper que conecta una variable directamente con UserDefaults. Si el valor en UserDefaults cambia, la vista se actualiza.
  11. ¿Qué es @SceneStorage? Similar a @AppStorage pero para persistir el estado de una escena específica (útil para restauración de estado en multitarea de iPad).
  12. ¿Qué es Binding.constant(value)? Crea un binding inmutable, útil principalmente para previsualizaciones (Previews) donde necesitas pasar un binding pero no necesitas lógica real.
  13. ¿Cómo comunicas cambios de una vista hija a un padre sin Bindings? Puedes usar Closures (callbacks) o PreferenceKeys.
  14. ¿Qué son las PreferenceKeys? Un mecanismo avanzado para pasar datos hacia arriba en la jerarquía (de hijo a padre), opuesto al flujo normal de datos.
  15. ¿Es buena práctica usar Singletons en SwiftUI? Generalmente no para la inyección de dependencias en vistas. Es mejor usar @EnvironmentObject o inyección en el inicializador para facilitar los tests.

🟠 Nivel 3: Layout y Diseño

  1. ¿Cuáles son los tres stacks principales? VStack (Vertical), HStack (Horizontal), ZStack (Profundidad/Superposición).
  2. ¿Qué hace un Spacer? Ocupa todo el espacio disponible en el eje de su stack contenedor, empujando al resto del contenido.
  3. ¿Cómo funciona Frame? Modifica el tamaño propuesto a la vista. .frame(maxWidth: .infinity) hace que la vista ocupe todo el ancho posible.
  4. ¿Qué es GeometryReader? Un contenedor que te da acceso al tamaño y coordenadas de su vista padre. Útil para diseños responsivos complejos.
  5. ¿Cuál es el problema principal de usar GeometryReader en todos lados? Puede romper el layout automático natural de SwiftUI y es costoso en rendimiento si se abusa; a menudo tiende a ocupar todo el espacio disponible.
  6. ¿Qué es LazyVStack y LazyHStack? Stacks que solo renderizan las vistas que son visibles en pantalla. Esencial para listas largas de scroll para mejorar el rendimiento.
  7. ¿Cómo se crea una cuadrícula (Grid)? Usando LazyVGrid o LazyHGrid junto con GridItem.
  8. ¿Qué es SafeArea? Las áreas de la pantalla obstruidas por elementos del sistema (el notch, la isla dinámica, la barra de home).
  9. ¿Cómo ignoras el Safe Area? Usando el modificador .ignoresSafeArea().
  10. ¿Cómo priorizas qué vista se encoge si no hay espacio? Usando .layoutPriority(Double). Las vistas con mayor prioridad mantienen su tamaño; las de menor prioridad se encogen o truncan.
  11. ¿Qué es el modificador .overlay()? Coloca una vista encima de otra (frente al usuario), similar a un ZStack pero acoplado al tamaño de la vista original.
  12. ¿Qué es el modificador .background()? Coloca una vista detrás de otra.
  13. ¿Cómo redondeas las esquinas de una vista? .cornerRadius() (deprecado) o .clipShape(RoundedRectangle(...)).
  14. ¿Cómo aplicas sombras? Con el modificador .shadow().
  15. ¿Qué es ImageScale? Define el tamaño relativo de los iconos SF Symbols (small, medium, large) independientemente de su tamaño de fuente.

🟣 Nivel 4: Listas y Navegación

  1. ¿Qué diferencia hay entre List y ForEach dentro de un ScrollView? List tiene apariencia nativa de sistema (estilo tabla de UIKit) y optimizaciones de carga (lazy) integradas. ScrollView + ForEach es totalmente personalizable pero no recicla celdas automáticamente a menos que uses LazyVStack.
  2. ¿Qué protocolo deben cumplir los elementos de una List? Identifiable, o debes proveer un id: \.self explícito.
  3. ¿Para qué sirve la propiedad id en Identifiable? Para que SwiftUI sepa distinguir qué fila es cual, especialmente al animar cambios, inserciones o borrados.
  4. ¿Cómo manejas la navegación en iOS 16+? Con NavigationStack y navigationDestination(for:).
  5. ¿Por qué se depreció NavigationView? Tenía comportamientos inconsistentes entre iPhone y iPad (split view) y el manejo programático de la navegación (deep linking) era difícil.
  6. ¿Cómo haces una navegación programática (ir a una pantalla por código)? Usando un NavigationPath o un binding a un array de datos dentro de NavigationStack.
  7. ¿Qué es NavigationLink? El botón o área que desencadena la transición a una nueva vista dentro de una pila de navegación.
  8. ¿Cómo muestras una ventana modal (Sheet)? Usando el modificador .sheet(isPresented: content:) o .sheet(item: content:).
  9. ¿Diferencia entre .sheet y .fullScreenCover? .sheet muestra la vista estilo carta (se ve parte de la vista anterior detrás), .fullScreenCover ocupa toda la pantalla.
  10. ¿Qué es TabView? El equivalente al UITabBarController, permite navegación por pestañas inferiores (o laterales en iPad/macOS).
  11. ¿Cómo creas un carrusel de imágenes paginado? Usando TabView con el estilo .tabViewStyle(.page).
  12. ¿Cómo añades un título a la barra de navegación? Con el modificador .navigationTitle("Título") aplicado a la vista dentro del stack.
  13. ¿Cómo añades botones a la barra de navegación? Con .toolbar { ... } y ToolbarItem.
  14. ¿Cómo muestras una alerta? Con el modificador .alert(), enlazado a un estado booleano o un objeto de error opcional.
  15. ¿Cómo implementas “Pull to Refresh”? Añadiendo el modificador .refreshable { ... } a una Lista o ScrollView.

🔴 Nivel 5: Interoperabilidad y Avanzado

  1. ¿Cómo usas una vista de UIKit en SwiftUI? Creando un struct que conforme a UIViewRepresentable.
  2. ¿Qué métodos debes implementar en UIViewRepresentable? makeUIView(context:) y updateUIView(_:context:).
  3. ¿Qué es el Coordinator en UIViewRepresentable? Actúa como el puente para recibir eventos de UIKit (como delegados o targets) y comunicarlos de vuelta a SwiftUI.
  4. ¿Cómo usas un UIViewController en SwiftUI? Usando UIViewControllerRepresentable.
  5. ¿Cómo usas una vista de SwiftUI en un proyecto de UIKit? Envolviéndola en un UIHostingController.
  6. ¿Qué es AnyLayout (iOS 16)? Un tipo que permite cambiar dinámicamente entre tipos de layout (ej. de VStack a HStack) manteniendo la identidad de las vistas para animaciones fluidas.
  7. ¿Cómo gestionas las animaciones explícitas? Envolviendo el cambio de estado en un bloque withAnimation { ... }.
  8. ¿Qué son las animaciones implícitas? El modificador .animation(.default, value: variable) que anima automáticamente cuando variable cambia.
  9. ¿Qué hace matchedGeometryEffect? Permite animar el movimiento de una vista de una posición/jerarquía a otra diferente, creando transiciones fluidas de “Hero animation”.
  10. ¿Qué es TimelineView? Una vista que se actualiza periódicamente según un horario, útil para relojes o animaciones complejas basadas en tiempo.
  11. ¿Qué es Canvas (la vista, no la preview)? Una vista para dibujo de gráficos 2D de alto rendimiento (similar a drawRect de CoreGraphics) usando un contexto de dibujo inmediato.
  12. ¿Cómo manejas tareas asíncronas al aparecer una vista? Usando el modificador .task. Es mejor que onAppearporque cancela automáticamente la tarea si la vista desaparece antes de terminar.
  13. ¿Qué es AsyncImage? Una vista nativa para descargar y mostrar imágenes desde una URL.
  14. ¿Cuál es la limitación de AsyncImage? No tiene caché de disco integrado por defecto (solo memoria temporal mientras la vista vive). Para caché real, se suelen usar librerías externas o implementaciones propias.
  15. ¿Qué es ViewBuilder? Un atributo de función (result builder) que permite construir vistas a partir de bloques de cierre, permitiendo sintaxis tipo DSL (como dentro de un VStack).
  16. ¿Puedes crear tus propios contenedores como VStack? Sí, usando el protocolo Layout (iOS 16+).
  17. ¿Qué es FocusState? Un property wrapper para controlar el foco del teclado en campos de texto (hacer que aparezca o desaparezca el teclado programáticamente).
  18. ¿Cómo soportas Modo Oscuro en colores personalizados? Definiendo el color en el Asset Catalog con variantes “Any” y “Dark”, o usando colores semánticos del sistema (.systemBackground).
  19. ¿Qué es Dynamic Type? La capacidad de la app de escalar el tamaño de las fuentes según la configuración del usuario. SwiftUI lo soporta por defecto.
  20. ¿Cómo limitas el número de líneas en un texto? .lineLimit(n).

⚫ Nivel 6: Arquitectura y Datos (Core Data / SwiftData)

  1. ¿Es MVVM la única arquitectura para SwiftUI? No. Aunque es la más común, patrones como “The Composable Architecture” (TCA) o Redux también son populares debido a la naturaleza declarativa de SwiftUI.
  2. ¿Cuál es el rol del ViewModel en SwiftUI? Transformar datos del modelo en estado listo para la vista y manejar la lógica de negocio (acciones del usuario).
  3. ¿Qué property wrapper se usa para inyectar un contexto de Core Data? @Environment(\.managedObjectContext).
  4. ¿Cómo haces un fetch de Core Data en una vista? Usando @FetchRequest.
  5. ¿Qué es SwiftData? El sucesor moderno de Core Data, diseñado puramente para Swift y SwiftUI, lanzado en iOS 17.
  6. ¿Cómo defines un modelo en SwiftData? Usando la macro @Model antes de la clase.
  7. ¿Cómo consultas datos en SwiftData dentro de una vista? Usando la macro @Query.
  8. ¿Qué problema tienen las vistas muy grandes en un solo archivo? El compilador tarda más en inferir los tipos, la previsualización es lenta y el código es difícil de leer. Se recomienda extraer subvistas.
  9. ¿Qué diferencia hay entre una propiedad calculada (var body: some View) y una subvista struct? La struct es mejor para el rendimiento porque SwiftUI puede cachearla y optimizar su redibujado de forma independiente. La propiedad calculada se reevalúa siempre que cambia el cuerpo del padre.
  10. ¿Cómo testeas una vista SwiftUI? Es difícil hacer Unit Test de vistas. Se recomienda usar UI Tests (XCUITest) o usar la librería ViewInspector para inspeccionar la jerarquía en unit tests.
  11. ¿Qué es el modificador .redacted(reason: .placeholder)? Convierte el contenido de la vista en bloques grises, ideal para estados de carga (skeletons) automáticos.
  12. ¿Cómo manejas errores globales? A menudo inyectando un gestor de errores en el Environment o usando un estado global que activa alertas en la vista raíz.
  13. ¿Qué es MainActor? Un atributo que asegura que el código se ejecute en el hilo principal. Los ViewModels (ObservableObject) suelen marcarse con @MainActor para asegurar que las actualizaciones de UI ocurran en el hilo correcto.
  14. ¿Cómo optimizas una lista que tiene lag al scrollear?
    1. Usar Identifiable correctamente. 2. Reducir la complejidad de cada fila. 3. Asegurar que las imágenes se cargan asíncronamente. 4. Evitar cálculos pesados en el body.
  15. ¿Para qué sirve EquatableView? Permite definir reglas personalizadas para decidir si una vista necesita redibujarse comparando su estado anterior y nuevo, evitando renders innecesarios.

⚪ Nivel 7: macOS y Multiplataforma

  1. ¿Funciona SwiftUI igual en macOS que en iOS? En un 90% sí, pero macOS tiene paradigmas diferentes (ventanas múltiples, barra de menú, eventos de ratón vs táctil).
  2. ¿Qué es Settings en la estructura App? Define la ventana de preferencias/configuración en macOS (Comando + ,).
  3. ¿Cómo detectas si estás en macOS o iOS en tiempo de compilación? Usando #if os(macOS) … #endif.
  4. ¿Cómo manejas el Hover del ratón en macOS/iPadOS? Usando el modificador .onHover { isHovering in ... }.
  5. ¿Qué es Commands en la estructura App? Permite modificar la barra de menú del sistema (Menú Archivo, Edición, etc.) en macOS.

♿ Nivel 8: Accesibilidad (El diferenciador clave)

Las grandes empresas (y Apple) valoran enormemente esto. Si ignoras esta sección, ignoras a millones de usuarios.

  1. ¿Cómo haces que una imagen decorativa sea ignorada por VoiceOver? Usando el modificador .accessibilityHidden(true).
  2. ¿Qué diferencia hay entre .accessibilityLabel y .accessibilityValue? El Label describe qué es el elemento (ej. “Volumen”), y el Value describe su estado actual (ej. “50%”).
  3. ¿Qué es .accessibilityHint? Una instrucción opcional que explica qué pasará si el usuario interactúa con el elemento (ej. “Toca dos veces para silenciar”).
  4. ¿Cómo agrupas varios textos para que VoiceOver los lea como una sola frase? Usando el modificador .accessibilityElement(children: .combine).
  5. ¿Qué es el orden de ordenación (Sort Priority) en accesibilidad? Define en qué orden lee VoiceOver los elementos. Se controla con .accessibilitySortPriority(Double).
  6. ¿Cómo soportas Dynamic Type en layouts complejos que podrían romperse? Usando ViewThatFits o detectando el sizeCategory en el entorno para cambiar de HStack a VStack si la letra es muy grande.
  7. ¿Qué es .accessibilityAddTraits? Añade características al elemento, como .isButton o .isHeader, para que el lector de pantalla sepa cómo tratarlo.
  8. ¿Cómo pruebas la accesibilidad sin un dispositivo físico? Usando la herramienta “Accessibility Inspector” en Xcode.
  9. ¿Cómo haces que un botón personalizado se comporte como un botón nativo para VoiceOver? Asegurándote de que tenga el trait .isButton y que no oculte su acción.
  10. ¿Qué es “Reduce Motion” y cómo lo respetas en SwiftUI? Es una preferencia de usuario para minimizar mareos. Se lee desde @Environment(\.accessibilityReduceMotion) y debes usarlo para desactivar o simplificar animaciones.

🎨 Nivel 9: Gráficos Avanzados, Animaciones y Layouts

  1. ¿Qué es el protocolo Animatable? Permite animar cambios en propiedades que no son animables por defecto (como los vértices de una forma personalizada) definiendo una animatableData.
  2. ¿Qué es AnimatablePair? Un tipo que permite animar dos valores simultáneamente dentro de animatableData (ej. coordenada X e Y).
  3. ¿Cuál es la diferencia entre .transition y .animation? .animation suaviza el cambio de propiedades de una vista existente (color, tamaño). .transition define cómo una vista entra o sale de la jerarquía (fade in, slide out).
  4. ¿Por qué una transición podría no funcionar? Generalmente porque la vista no se está eliminando/insertando realmente en el árbol (ej. usar opacity en lugar de un if condicional).
  5. ¿Qué es Canvas en términos de gráficos (SwiftUI 3.0+)? Una vista que proporciona un contexto de gráficos inmediato (similar a drawRect de Core Graphics) de altísimo rendimiento, ideal para partículas o dibujo complejo.
  6. ¿Qué es TimelineView y para qué sirve en animaciones? Permite redibujar una vista periódicamente (incluso frame a frame), útil para animaciones basadas en tiempo o física que no dependen de cambios de estado.
  7. ¿Cómo creas una forma personalizada (Custom Shape)? Creando un struct que conforme a Shape e implementando path(in rect: CGRect).
  8. ¿Qué es un Shader en SwiftUI (iOS 17+)? Permite aplicar efectos visuales escritos en Metal (MSL) directamente a las vistas usando modificadores como .colorEffect o .distortionEffect.
  9. ¿Qué es el modificador .drawingGroup()? Aplana la jerarquía de vistas en una sola imagen renderizada por Metal. Se usa para solucionar problemas de rendimiento en listas complejas o gráficos pesados.
  10. ¿Qué es Anchor<T>? Un tipo opaco que almacena información geométrica de una vista para ser usada por otra vista en la jerarquía (generalmente con preferences).
  11. ¿Cómo funciona matchedGeometryEffect si tienes dos vistas con el mismo ID en pantalla? Es un comportamiento indefinido y causará fallos visuales. Los IDs deben ser únicos por grupo de animación activo.
  12. ¿Qué es Layout protocol (iOS 16)? Permite crear contenedores personalizados (como tu propio Grid o Flow Layout) definiendo cómo medir y colocar las subvistas.
  13. ¿Diferencia entre Path y Shape? Shape es una Vista que se ajusta a un espacio. Path es la descripción matemática de una línea/curva que puede usarse dentro de una Shape.
  14. ¿Cómo aplicas un gradiente a un texto? Usando .foregroundStyle(Gradient...) (iOS 15+).
  15. ¿Qué es VisualEffectView en SwiftUI? No existe directamente, se usa Material (ej. .background(.ultraThinMaterial)).

⚡ Nivel 10: Concurrencia y Ciclo de Vida (Swift 5.5+)

  1. ¿Por qué usar .task en lugar de .onAppear? .task soporta async/await nativamente y se cancela automáticamente si la vista se destruye antes de que termine la tarea.
  2. ¿Qué significa @MainActor en un ViewModel? Garantiza que todas las propiedades y métodos de esa clase se accedan/ejecuten en el hilo principal, previniendo errores de actualización de UI desde hilos de fondo.
  3. ¿Qué pasa si modificas una propiedad @Published desde un hilo secundario? SwiftUI lanzará un warning en tiempo de ejecución (purple warning) y podría causar crashes o comportamientos extraños en la UI.
  4. ¿Qué es Sendable y cómo afecta a SwiftUI? Es un protocolo que indica que es seguro pasar un dato entre hilos. Los datos que pasas a vistas (especialmente en closures de .task) deberían ser Sendable.
  5. ¿Cómo manejas una carrera de datos (Data Race) en SwiftUI? Usando actores (actor), aislamiento con @MainActor, y evitando estados compartidos mutables sin protección.
  6. ¿El cuerpo (body) de una vista se ejecuta en el Main Thread? Sí, siempre.
  7. ¿Cómo detienes una tarea en curso cuando el usuario navega atrás? Si usas .task, es automático. Si usas Task { }manual en onAppear, debes guardar la referencia y llamar a .cancel() en onDisappear.
  8. ¿Qué es AsyncSequence en el contexto de SwiftUI? Permite iterar sobre flujos de datos asíncronos (como notificaciones o bytes de descarga) actualizando la UI paso a paso.
  9. ¿Puedes usar await dentro de un botón? No directamente en el cierre del botón. Debes envolver la llamada en Task { await ... }.
  10. ¿Qué es ViewInspector? No es nativo, pero es la librería open-source estándar de facto para realizar Unit Tests sobre la jerarquía de vistas de SwiftUI.

📱 Nivel 11: Ecosistema (Widgets, WatchOS, Live Activities)

  1. ¿Qué framework se usa para crear Widgets de pantalla de inicio? WidgetKit, que utiliza SwiftUI exclusivamente.
  2. ¿Qué es un TimelineEntry en WidgetKit? Un objeto que representa el estado del widget en un punto específico del tiempo.
  3. ¿Por qué las animaciones están limitadas en los Widgets? Porque los widgets son “snapshots” serializados, no vistas vivas ejecutándose constantemente (aunque iOS 17 mejoró esto).
  4. ¿Qué es una Live Activity? Una notificación interactiva y persistente en la pantalla de bloqueo (y Dynamic Island) para eventos en tiempo real (ej. delivery de comida).
  5. ¿Qué es DynamicIsland? La API en SwiftUI para definir cómo se ve tu Live Activity en la “isla” del iPhone 14 Pro/15.
  6. ¿En watchOS, qué sustituye a NavigationView o NavigationStack para la jerarquía base? Generalmente se usa NavigationStack igual, pero el estilo de paginación (.tabViewStyle(.verticalPage)) es muy común.
  7. ¿Qué es .digitalCrownRotation? Un modificador exclusivo de watchOS para leer el valor de la corona digital.
  8. ¿Cómo compartes código de UI entre una App de iOS y un Widget? Extrayendo las vistas a un paquete local (Swift Package) o incluyéndolas en ambos Targets.
  9. ¿Qué es App Clips? Una pequeña parte de tu app (menos de 10-15MB) que se ejecuta instantáneamente sin instalación completa. Se construye con SwiftUI.
  10. ¿Qué es WidgetURL? Un modificador que define qué URL se abre en la app principal cuando el usuario toca el widget.

🧩 Nivel 12: Arquitectura de Datos Avanzada

  1. ¿Qué es Preference en SwiftUI? Un canal de comunicación de hijos a padres. Los hijos envían datos, el padre los recolecta y reduce.
  2. ¿Qué es AnchorPreference? Permite pasar límites y coordenadas de una vista hija a un padre (útil para tooltips o resaltados guiados).
  3. ¿Cómo inyectas dependencias en un Environment personalizado? Creando una EnvironmentKey personalizada y extendiendo EnvironmentValues.
  4. ¿Qué problema resuelve AnyView y por qué deberías evitarlo? Permite borrar el tipo de una vista (Type Erasure) para devolver tipos distintos en un if/else. Debe evitarse porque destruye la optimización de “diffing” de SwiftUI, reduciendo el rendimiento.
  5. En lugar de AnyView, ¿qué deberías usar? @ViewBuilder o Group.
  6. ¿Qué es el patrón “Coordinator” en SwiftUI? Una clase externa encargada de la lógica de navegación, separando la vista de la decisión de “a dónde ir”.
  7. ¿Es posible usar Redux en SwiftUI? Sí, es muy compatible. Se suele tener un Store global como ObservableObject y Reducers puros.
  8. ¿Qué diferencia hay entre @StateObject y una variable global estática? @StateObject está ligado al ciclo de vida de la vista (se libera si la vista muere). La global vive siempre (memory leak potencial).
  9. ¿Cómo fuerzas una actualización de la vista manualmente (aunque no se recomienda)? Usando objectWillChange.send() en un ObservableObject.
  10. ¿Cómo detectas cuando la app pasa a segundo plano? Usando .onChange(of: scenePhase).

🛠 Nivel 13: Depuración y Rendimiento (Troubleshooting)

  1. ¿Por qué mi vista se redibuja constantemente (loop infinito)? Probablemente estás modificando un @State dentro del body o en un constructor, lo que dispara un nuevo render, que vuelve a modificar el estado.
  2. ¿Cómo identificas qué vista está causando lentitud? Usando el “SwiftUI View Hierarchy” en Instruments o la opción “Color Blended Layers” en el simulador.
  3. ¿Por qué List tiene mal rendimiento con miles de elementos complejos? A veces List no recicla celdas tan eficientemente como UICollectionView. Se sugiere simplificar la celda o usar LazyVStack dentro de un ScrollView si Listfalla.
  4. ¿Qué significa el error “Modifying state during view update, this will cause undefined behavior”? Que estás cambiando datos mientras SwiftUI está calculando el layout (ej. dentro de un GeometryReader actualizando un @Statepadre directamente).
  5. ¿Cómo solucionas el error anterior? Envolviendo el cambio de estado en DispatchQueue.main.async o usando .onAppear / .task.
  6. ¿Qué impacto tiene usar .shadow() en el rendimiento? Alto. Las sombras requieren renderizado fuera de pantalla (off-screen pass). Mejor usar imágenes pre-renderizadas o sombras simuladas si es posible.
  7. ¿Qué es el “Opaque Return Type” y cómo afecta a la compilación? (some View). Ayuda al compilador a trabajar más rápido al no tener que inferir toda la cadena de tipos genéricos anidados.
  8. ¿Por qué mi @Published no actualiza la vista? Quizás la vista no está observando el objeto con @ObservedObject o @StateObject, o la actualización ocurre en una propiedad anidada de una clase (las clases son tipos de referencia y @Published no observa cambios profundos automáticamente).

🧪 Nivel 14: Swift Charts, MapKit y Nuevas APIs

  1. ¿Cómo creas un gráfico de barras simple? Usando el framework Charts y la vista Chart { BarMark(...) }.
  2. ¿Qué es Plottable? El protocolo que deben cumplir los datos para ser representados en Swift Charts (Strings, Ints, Dates, etc.).
  3. ¿Cómo muestras el mapa nativo en SwiftUI (iOS 17)? Usando la vista Map(). Ya no requiere binding de región obligatorio en las versiones nuevas.
  4. ¿Qué es MapAnnotation vs Marker? Marker es el pin estándar (globo) con mejor rendimiento. MapAnnotation permite usar una vista SwiftUI totalmente personalizada como pin.
  5. ¿Qué es ShareLink? La vista nativa para presentar la hoja de compartir (Share Sheet) del sistema.
  6. ¿Cómo implementas “Búsqueda” en una lista? Usando el modificador .searchable(text: $text).
  7. ¿Qué es contentTransition? Define cómo cambia el contenido de una vista (ej. números que giran estilo contador) usando .contentTransition(.numericText()).

🔥 Nivel 15: Preguntas Trampa / Escenarios de Código

El entrevistador te muestra código y pregunta: “¿Qué pasa aquí?”

  1. Escenario: Tienes un VStack con Spacing: 0 y dos rectángulos de altura 50. ¿La altura total es 100? Respuesta: No necesariamente. El Safe Area o el contenedor padre podrían comprimirlos si no hay espacio.
  2. Escenario: Usas @State para un objeto de clase (class User). ¿Funciona? Respuesta: Funciona, pero la vista no se actualizará cuando cambien las propiedades dentro de User, porque @State solo observa el cambio del puntero de la clase, no sus contenidos.
  3. Escenario: Tienes un NavigationLink dentro de una List pero no funciona al tocar. Respuesta: A menudo ocurre si tienes un Button dentro de la fila (row) que captura el toque, o si olvidaste el NavigationStack padre.
  4. Escenario: Text("Hola").padding().background(Color.red).padding() vs Text("Hola").padding().padding().background(Color.red).Respuesta: En el primero, el rojo rodea al texto con un margen. En el segundo, el rojo rodea al texto con doble margen (se ve más grande el bloque rojo, o más lejos del texto dependiendo de la interpretación visual). El orden importa.
  5. Escenario: ¿Por qué un LazyVGrid dentro de un ScrollView horizontal se ve mal? Respuesta: Porque LazyVGrid crece verticalmente. Deberías usar LazyHGrid dentro de un Scroll horizontal.
  6. Escenario: Intentas aplicar .frame a una imagen, pero no cambia de tamaño. Respuesta: Olvidaste .resizable() antes del frame.
  7. Escenario: ¿Puede un @Binding ser opcional (Binding<Bool?>)? Respuesta: Sí, es posible.
  8. Escenario: ¿Qué pasa si llamas a una función impura en el bodyRespuesta: Se ejecutará múltiples veces de forma impredecible, causando efectos secundarios indeseados (bugs).
  9. Escenario: ¿Cómo ocultas la barra de navegación? Respuesta: .toolbar(.hidden) o .navigationBarHidden(true) (deprecado).
  10. Escenario: Tienes un ForEach con un rango 0..<items.count. ¿Es seguro? Respuesta: Es peligroso. Si el array cambia de tamaño, causará un crash “Index out of range”. Siempre usa ForEach(items) con Identifiable.

🏆 Nivel 16: El Toque Maestro (Miscellaneous)

  1. ¿Qué es FocusState? Controla qué campo de texto tiene el foco del teclado.
  2. ¿Qué es SubmitLabel? Cambia el botón “Intro” del teclado (ej. a “Buscar”, “Ir”, “Siguiente”).
  3. ¿Cómo detectas capturas de pantalla? Escuchando la notificación userDidTakeScreenshotNotification en onReceive.
  4. ¿Cómo añades un menú contextual (larga pulsación)? Con el modificador .contextMenu.
  5. ¿Qué es Menu en SwiftUI? Un botón que despliega una lista de opciones al pulsarse (no requiere pulsación larga).
  6. ¿Cómo usas fuentes personalizadas? Añadiendo el archivo a Info.plist y usando .font(.custom("Nombre", size: 12)).
  7. ¿Qué es Label? Una vista que combina un icono y un texto automáticamente alineados.
  8. ¿Cómo fuerzas el modo claro (Light Mode) en una vista específica? .preferredColorScheme(.light).
  9. ¿Qué es Stepper? Un control para incrementar/decrementar un valor numérico.
  10. ¿Qué es DisclosureGroup? Una vista colapsable (acordeón) que muestra u oculta contenido.
  11. ¿Cómo haces “Swipe Actions” en una lista? Usando el modificador .swipeActions en la celda.
  12. ¿Qué es OutlineGroup? Para mostrar estructuras de datos jerárquicas (árboles) en una lista expandible.
  13. ¿Cómo alineas texto a la izquierda en un VStack? VStack(alignment: .leading).
  14. ¿Por qué Spacer() no funciona en un ZStack? Porque ZStack superpone elementos, no los distribuye en un eje.
  15. ¿Qué es EmptyView? Una vista que no ocupa espacio ni renderiza nada. Útil como retorno por defecto en @ViewBuilder.
  16. ¿Qué es Divider? Una línea visual delgada (horizontal o vertical según el stack) para separar contenido.
  17. ¿Cómo detectas la orientación del dispositivo? Usando GeometryReader y comparando ancho vs alto, o escuchando cambios en UIDevice.
  18. ¿Qué es ScaledMetric? Un property wrapper que escala un valor numérico (como un tamaño de icono) proporcionalmente a la configuración de tamaño de texto del usuario.
  19. ¿Puedes usar CoreData sin NSPersistentCloudKitContainer en SwiftUI? Sí, pero pierdes la sincronización automática con iCloud.
  20. Si tuvieras que definir SwiftUI en una frase para convencer a un manager, ¿qué dirías? “SwiftUI reduce el código de UI en un 60%, elimina categorías enteras de bugs de estado y acelera la iteración de diseño drásticamente gracias a su naturaleza declarativa y previsualizaciones en tiempo real.”
Leave a Reply

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

Previous Article

Cómo seleccionar múltiples items en un Picker en SwiftUI

Next Article

165 preguntas de entrevistas iOS sobre Swift

Related Posts