wandres.dev
SWIFTUI AVANZADO · @Observable y animaciones

Animaciones y transiciones

SwiftUI anima solo: cambias un estado y describes cómo transicionar. withAnimation, .animation, transiciones y las phase animations modernas.

⏱ 13 min

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.

🎯 Al terminar esta lección sabrás
  • 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' cambie
💡
Elige 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
  1. Haz que una forma cambie de tamaño con withAnimation(.spring).
  2. Usa .animation(_, value:) para animar un cambio de color con un Toggle.
  3. Muestra/oculta una vista con una .transition combinada.
  4. Aplica un .phaseAnimator a un icono para que pulse en bucle.