Puntos clave
View Protocol es el protocolo central de SwiftUI. Requiere una única propiedad: var body: some View. body es una propiedad computada que devuelve la descripción de la UI. SwiftUI llama a body en cada cambio de estado y renderiza el resultado en la GPU.
@ViewBuilder es un Result Builder para Views. Permite escribir múltiples Views dentro de un closure sin return y sin TupleView. Soporta if/else, switch, ForEach. Todos los contenedores (VStack, HStack, ZStack, Group) usan @ViewBuilder. Una alternativa es Group { … } para agrupar sin layout. some View es un Opaque Type. El compilador conoce el tipo concreto de View (Text, Button, VStack, etc.), pero lo devuelve externamente como some View. Esto permite cambiar el tipo de body sin modificar la firma. ViewModifier — modificador de View: .font(), .padding(), .background(). Modificador personalizado mediante ViewModifier protocol y .modifier().
// Ejemplo de View con @ViewBuilder y NavigationStack
struct ContentView: View {
@State private var items = ["Item 1", "Item 2"]
var body: some View {
NavigationStack {
List(items, id: .self) { item in
NavigationLink(item) {
DetailView(item: item)
}
}
.navigationTitle("Items")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button("Add") {
items.append("New Item")
}
}
}
}
}
}
// DetailView con @StateObject
struct DetailView: View {
let item: String
@StateObject private var viewModel = DetailViewModel()
var body: some View {
Text(item)
.task {
await viewModel.loadDetails(for: item)
}
}
}NavigationStack (iOS 16+) — navegación basada en datos. Toma una ruta (array de valores hashable) y muestra el destino mediante navigationDestination. Reemplaza NavigationLink con vistas de destino. NavigationLink — botón para navegar por la pila. List — lista vertical con secciones, deslizamientos, eliminación y arrastre. Form — un List especializado para ajustes: secciones, selectores, interruptores, campos de texto. Section — agrupación en List/Form con cabecera y pie. ViewModifier — modificadores personalizados para reutilizar estilos. .modifier(CustomModifier()) — aplicación.
List en SwiftUI es el equivalente de UITableView. Soporta .onDelete, .onMove, .refreshable. SwipeActions — .swipeActions { Button("Eliminar", role: .destructive) { } }. Form — optimizado para ajustes: DatePicker, Toggle, Stepper, Picker. Section con header/footer — para agrupar. OutlineGroup — listas jerárquicas (equivalente de UITableView con secciones). DisclosureGroup — sección plegable con contenido. IT Sectr recomienda List para datos y Form para ajustes.
PreviewProvider — protocolo para vistas previas en Xcode Canvas. Canvas — vista previa interactiva de SwiftUI (requiere @main y Swift 5.9+). @ScaledMetric — tamaño adaptable que escala con Dynamic Type.
Property Wrappers son la base de la gestión de estado en SwiftUI. @State — estado local (value type). @Binding — conexión con el estado padre. @StateObject — crea un ObservableObject. SwiftUI gestiona el ciclo de vida del objeto. @ObservedObject — observa un ObservableObject externo. @EnvironmentObject — objeto del entorno (inyección de dependencias mediante .environmentObject()). @Environment — valores del sistema (.colorScheme, .locale). @AppStorage — UserDefaults. @FetchRequest — consulta de Core Data. @FocusState — foco de entrada.
| Wrapper | Propósito | Propiedad |
|---|---|---|
| @State | Estado local (value type) | La View posee |
| @Binding | Conexión con estado padre | El padre posee |
| @StateObject | Crea ObservableObject | La View posee |
| @ObservedObject | Observa objeto externo | Propietario externo |
| @EnvironmentObject | Objeto del entorno | El ancestro posee |
| @Environment | Valor del sistema | El sistema |
| @AppStorage | UserDefaults | UserDefaults |
| @FocusState | Foco de entrada | La View posee |
@StateObject vs @ObservedObject: @StateObject crea un objeto, @ObservedObject lo observa. Usa @StateObject para la creación inicial del modelo en la jerarquía, @ObservedObject para pasar a vistas hijas. @FocusState — gestión del foco: .focused($field, equals: .email). Soporta enum para múltiples campos.
@Environment — valores del sistema: colorScheme, locale, sizeCategory, layoutDirection, managedObjectContext. Custom Environment Values — valor personalizado mediante EnvironmentKey. Se usa para inyección de dependencias: pasar servicios sin parámetros explícitos. Modificador .environment() — establece un valor en la jerarquía. @EnvironmentObject — ObservableObject de .environmentObject(). Se diferencia de @Environment en que pasa un tipo por referencia. IT Sectr recomienda @Environment para valores del sistema y @EnvironmentObject para servicios.
.task{} — operación asíncrona al aparecer la vista. Cancelación automática al desaparecer. Reemplaza .onAppear para async/await. .onAppear{} — operación síncrona al aparecer. .onDisappear{} — operación al desaparecer. .onChange(of:) — reacción a cambios de valor. .onReceive(Publisher) — reacción al publicador de Combine. Ciclo de vida de la View en SwiftUI: init → onAppear → body (renderizado) → onDisappear. Al cambiar el estado: body → diff → rerenderizado. IT Sectr recomienda .task para carga asíncrona y .onAppear para analytics.
.animation() — modificador de animación. .transition() — animación de aparición/desaparición. withAnimation — animación explícita de cambios de estado. matchedGeometryEffect — animación entre diferentes vistas (hero animation). PhaseAnimator (iOS 17+) — animación multifase basada en enum. KeyframeAnimator (iOS 17+) — animación fotograma a fotograma con keyframes. Las animaciones de SwiftUI se ejecutan en la GPU mediante Core Animation. IT Sectr recomienda .spring() para animaciones naturales y .interpolatingSpring para efectos físicos.
ObservableObject — protocolo para objetos con propiedades @Published. SwiftUI se suscribe al publicador objectWillChange. @Published — publica cambios de propiedad. @StateObject — crea ObservableObject, gestiona el ciclo de vida. @ObservedObject — observa externo. Combine — framework para programación reactiva. @EnvironmentObject — DI mediante entorno. .environmentObject() establece, @EnvironmentObject lee. MVVM — arquitectura estándar: View (SwiftUI) — ViewModel (ObservableObject) — Model. IT Sectr recomienda MVVM + @StateObject para ViewModels principales.
class UserViewModel: ObservableObject {
@Published var users: [User] = []
@Published var isLoading = false
func loadUsers() async {
isLoading = true
defer { isLoading = false }
do {
users = try await api.fetchUsers()
} catch {
print("Error: \(error)")
}
}
}
struct UsersView: View {
@StateObject private var viewModel = UserViewModel()
var body: some View {
List(viewModel.users, id: \.id) { user in
Text(user.name)
}
.task { await viewModel.loadUsers() }
.overlay {
if viewModel.isLoading { ProgressView() }
}
}
}Accesibilidad en SwiftUI: .accessibilityLabel(), .accessibilityHint(), .accessibilityValue(), .accessibilityAddTraits(). VoiceOver lee las etiquetas de accesibilidad. Dynamic Type — @ScaledMetric, @DynamicProperty. Localización: String(localized:) (SwiftUI + String Catalog). LocalizedStringKey — traducción automática. Reglas de plural — mediante String Catalog (one, few, many, other). Right-to-Left (árabe, hebreo) — soportado automáticamente. .environment(.layoutDirection, .rightToLeft). IT Sectr recomienda etiquetas de accesibilidad para todos los elementos interactivos.
struct AccessibleButton: View {
let action: () -> Void
var body: some View {
Button(action: action) {
Label("Settings", systemImage: "gear")
}
.accessibilityLabel("Open Settings")
.accessibilityHint("Double tap to navigate to settings screen")
.accessibilityAddTraits(.isButton)
}
}
// Soporte de Dynamic Type
struct ScalableText: View {
@ScaledMetric private var fontSize: CGFloat = 17
var body: some View {
Text("Hello, World!")
.font(.system(size: fontSize))
}
}Swift Charts (iOS 16+) — framework para construir gráficos. Chart { } — contenedor básico. BarMark, LineMark, PointMark, AreaMark, RuleMark — marcas. ForEach para datos. ChartAxis — personalización de ejes. .chartXAxis, .chartYAxis. ChartLegend — leyenda. Interpolación — catmullRom, linear, step. Animación — .animation() para Chart. IT Sectr recomienda Swift Charts para gráficos integrados y Charts (DGCharts) para complejos.
import Charts
struct MonthlySales: Identifiable {
let id = UUID()
let month: String
let sales: Double
}
struct SalesChart: View {
let data: [MonthlySales]
var body: some View {
Chart(data) { item in
BarMark(
x: .value("Month", item.month),
y: .value("Sales", item.sales)
)
.foregroundStyle(.blue.gradient)
}
.chartXAxisLabel("Month")
.chartYAxisLabel("Sales")
.frame(height: 200)
.padding()
}
}Swift Package Manager (SPM) — el gestor de dependencias de Apple. Integrado en Xcode. Soporta: paquetes binarios, recursos, tests, swift-6 strict concurrency. Publicación de paquetes mediante GitHub con etiqueta semver. SPM es el estándar de facto para dependencias Swift, reemplazando CocoaPods y Carthage. IT Sectr recomienda SPM para todos los proyectos nuevos.
Swift Concurrency (async/await, TaskGroup, AsyncSequence) — async/await integrado en Swift 5.5+. Task — unidad de asincronía. TaskGroup — tareas paralelas. AsyncSequence — secuencia asíncrona (AsyncStream, AsyncAlgorithms). Task Local Values — datos contextuales para Task. Swift Concurrency reemplaza completamente a Combine para operaciones asíncronas.
Preguntas frecuentes
View Protocol es el protocolo base. Requiere var body: some View. body es la descripción de la UI, renderizada en la GPU.
@ViewBuilder es un Result Builder para múltiples Views. Permite if/else, switch, ForEach dentro de contenedores.
@StateObject crea un objeto. @ObservedObject observa uno existente. @StateObject para la primera creación en la jerarquía.
NavigationStack — navegación basada en datos. path-based, deep linking. Reemplaza NavigationView.
@FocusState — gestión del foco de entrada. Modificador .focused(). Soporta enum para múltiples campos.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.