Animaciones y transiciones
SwiftUI anima solo: cambias un estado y describes cómo transicionar. withAnimation, .animation, transiciones y las phase animations modernas.
Animar en SwiftUI es casi mágico: no defines fotogramas ni temporizadores. Cambias un valor de estado dentro de una animación, y SwiftUI interpola suavemente entre el antes y el después. Menos código, mejores resultados.
- Animar cambios de estado con
withAnimation. - El modificador
.animation(_, value:). - Transiciones al aparecer y desaparecer.
- Animaciones por fases (phase animator).
withAnimation: anima un cambio
Envuelve el cambio de estado en withAnimation y todo lo que dependa de ese estado se anima:
struct Caja: View { @State private var grande = false var body: some View { VStack { RoundedRectangle(cornerRadius: 20) .frame(width: grande ? 200 : 100, height: 100) .foregroundStyle(.blue) Button("Cambiar") { withAnimation(.spring) { // .spring, .easeInOut, .bouncy… grande.toggle() } } } }}El rectángulo crece o encoge con una animación de muelle. No animaste el tamaño: animaste el cambio de estado, y SwiftUI hizo el resto.
.animation(_, value:)
Alternativa: adjunta la animación a una vista y dispárala cuando cambie un valor concreto:
Circle() .fill(activo ? .green : .gray) .scaleEffect(activo ? 1.2 : 1.0) .animation(.easeInOut, value: activo) // anima cuando 'activo' cambieElige la curva adecuada
.spring y .bouncy dan sensación viva y natural (ideal para interacciones). .easeInOut es sobrio y elegante. .linear para movimiento constante. Empieza con .spring: es la que mejor sienta a la mayoría de interacciones táctiles, y por algo es la favorita del diseño de Apple.
Transiciones: aparecer y desaparecer
Cuando una vista entra o sale de la jerarquía, .transition define cómo:
if mostrando { Text("¡Sorpresa!") .transition(.scale.combined(with: .opacity))}// …dispara con:withAnimation { mostrando.toggle() }Combina transiciones (.slide, .scale, .opacity, .move(edge:)) para efectos ricos.
Animaciones por fases
Para animaciones que recorren varios estados en bucle (un icono que “respira”, un aviso que pulsa), .phaseAnimator:
Image(systemName: "heart.fill") .foregroundStyle(.red) .phaseAnimator([1.0, 1.3, 1.0]) { vista, escala in vista.scaleEffect(escala) }SwiftUI recorre las fases [1.0, 1.3, 1.0] animando entre ellas automáticamente.
Anima el estado, no los píxeles
El cambio de mentalidad clave: en otros frameworks defines la animación (mueve de X a Y en 0.3s). En SwiftUI defines dos estados (pequeño/grande, visible/oculto) y le dices que la transición entre ellos sea animada. SwiftUI calcula todos los fotogramas intermedios. Esto hace que las animaciones sean interrumpibles y reversibles gratis: si el usuario cambia de idea a mitad, SwiftUI reacciona con fluidez, porque siempre está animando hacia el estado actual, no reproduciendo un guion fijo.
Dale vida a la interfaz
- Haz que una forma cambie de tamaño con
withAnimation(.spring). - Usa
.animation(_, value:)para animar un cambio de color con unToggle. - Muestra/oculta una vista con una
.transitioncombinada. - Aplica un
.phaseAnimatora un icono para que pulse en bucle.