UIKit Dynamics es un framework de animación física en iOS (UIKit) que permite que las Views interactúen según las leyes de la física real: gravedad, colisiones, elasticidad y fuerzas de atracción. Este artículo explica los componentes de UIDynamicAnimator, los tipos de comportamientos (behaviors) y los casos prácticos de uso.
Puntos clave
UIKit Dynamics es un framework de simulación física introducido por Apple en iOS 7 (2013). A diferencia de UIView.animate (transiciones lineales) y Core Animation (animación de capas), UIKit Dynamics simula interacciones físicas reales: gravedad, colisiones, fuerzas, elasticidad y fricción. El desarrollador añade comportamientos a UIDynamicAnimator y el sistema calcula automáticamente la física en cada fotograma.
El framework funciona a 60/120 FPS y utiliza un motor físico integrado basado en simulación de cuerpos rígidos. UIKit Dynamics no requiere conocimientos de física o matemáticas — solo hay que aplicar un comportamiento ya preparado y configurar sus parámetros.
Según Apple, UIKit Dynamics es adecuado para efectos de UI (animación de pilas de cartas, vibración de iconos, física de interfaz), pero no está diseñado para juegos — para juegos utiliza SceneKit o SpriteKit.
UIDynamicAnimator es la clase central de UIKit Dynamics. Se inicializa con una reference view (normalmente la vista del controlador) y gestiona todos los comportamientos activos. Cada fotograma UIDynamicAnimator recalcula posiciones, velocidades y aceleraciones de todos los elementos añadidos según las leyes físicas.
El método addBehavior añade un comportamiento (o un UIDynamicBehavior complejo), removeBehavior lo elimina. El animador se pausa automáticamente cuando todos los objetos alcanzan un estado de reposo (continuar sin colisiones ni fuerzas). El método delegado — UIDynamicAnimatorDelegate — notifica sobre la pausa y reanudación de la simulación.
Cualquier objeto que participe en la física debe implementar el protocolo UIDynamicItem. UIView y UICollectionViewLayoutAttributes ya lo implementan. El protocolo requiere las propiedades: bounds, center, transform. Si el objeto es personalizado — implementa el protocolo manualmente.
UIKit Dynamics incluye siete tipos de comportamientos incorporados, cada uno modela un efecto físico específico. Los comportamientos se pueden combinar: por ejemplo, gravedad + colisiones + elasticidad crean el efecto de objetos que caen y rebotan.
| Behavior | Efecto físico | Parámetros clave |
|---|---|---|
| UIGravityBehavior | Gravedad (vector de fuerza) | gravityDirection (dx, dy), magnitude |
| UICollisionBehavior | Colisiones de objetos y bordes | collisionMode, translucence, collisionDelegate |
| UIAttachmentBehavior | Conexión (resorte/cable) | anchorPoint, length, damping, frequency |
| UISnapBehavior | Atracción a punto con amortiguación | snapPoint, damping (0-1) |
| UIPushBehavior | Empuje/impulso (continuo o instantáneo) | pushDirection, magnitude, mode |
| UIDynamicItemBehavior | Propiedades físicas del objeto | elasticity, friction, density, resistance |
| UIFieldBehavior | Campos de fuerza (vórtice, magnético, radial) | position, strength, falloff, region |
Para una física realista de objetos se necesitan varios comportamientos simultáneamente. Por ejemplo, para una carta que cae: UIGravityBehavior (fuerza de gravedad), UICollisionBehavior (colisión con el fondo), UIDynamicItemBehavior (elasticidad: 0.4 para rebote). Todos los comportamientos se añaden a un mismo UIDynamicAnimator.
El código Swift para UIKit Dynamics crea un UIDynamicAnimator y añade comportamientos. El siguiente ejemplo demuestra la gravedad con múltiples objetos, colisiones y propiedades físicas personalizadas.
import UIKit
class PhysicsViewController: UIViewController {
var animator: UIDynamicAnimator!
override func viewDidLoad() {
super.viewDidLoad()
// 1. Crear animador con vista de referencia
animator = UIDynamicAnimator(referenceView: view)
// 2. Crear objetos que caen
let redView = UIView(frame: CGRect(x: 100, y: 50, width: 60, height: 60))
redView.backgroundColor = .systemRed
redView.layer.cornerRadius = 8
view.addSubview(redView)
let blueView = UIView(frame: CGRect(x: 200, y: 30, width: 60, height: 60))
blueView.backgroundColor = .systemBlue
blueView.layer.cornerRadius = 8
view.addSubview(blueView)
// 3. Gravedad
let gravity = UIGravityBehavior(items: [redView, blueView])
gravity.gravityDirection = CGVector(dx: 0, dy: 1)
gravity.magnitude = 0.8
animator.addBehavior(gravity)
// 4. Colisiones
let collision = UICollisionBehavior(items: [redView, blueView])
collision.translatesReferenceBoundsIntoBoundary = true
collision.collisionDelegate = self
animator.addBehavior(collision)
// 5. Propiedades físicas
let itemBehavior = UIDynamicItemBehavior(items: [redView, blueView])
itemBehavior.elasticity = 0.6
itemBehavior.friction = 0.3
itemBehavior.density = 1.0
animator.addBehavior(itemBehavior)
// 6. Comportamiento Snap al tocar
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap))
view.addGestureRecognizer(tap)
}
@objc
func handleTap(_ gesture: UITapGestureRecognizer) {
let point = gesture.location(in: view)
// Comportamiento Snap para cada objeto
for subview in view.subviews where subview is UIView {
animator.removeAllBehaviors()
let snap = UISnapBehavior(item: subview, snapTo: point)
snap.damping = 0.5
animator.addBehavior(snap)
}
}
}
extension PhysicsViewController: UICollisionBehaviorDelegate {
func collisionBehavior(_ behavior: UICollisionBehavior,
beganContactFor item1: UIDynamicItem,
with item2: UIDynamicItem,
at point: CGPoint) {
print("Colisión en: (punto)")
}
}El ejemplo crea dos Views con gravedad, colisiones y propiedades físicas. UISnapBehavior al tocar atrae los objetos al punto táctil con amortiguación de 0.5. UICollisionBehaviorDelegate rastrea el inicio de colisiones para efectos de sonido y visuales.
UIKit Dynamics se utiliza en aplicaciones iOS para física de interfaz no relacionada con juegos. Escenarios populares: animación de pilas de cartas (UISnapBehavior para atracción al centro), vibración de pantalla al producirse un error (UIDynamicItemBehavior + UIPushBehavior), efecto de "estrellas fugaces" en onboarding (gravity + collision + field behavior).
Para rendimiento, UIKit Dynamics recomienda no más de 15-20 objetos simultáneos con física. Cada objeto requiere cálculos de colisiones y fuerzas en cada fotograma. Si se supera el límite, usa CALayer en lugar de UIView — Core Animation procesa las capas de forma más eficiente.
Preguntas frecuentes
UIKit Dynamics modela interacciones físicas (gravedad, colisiones, fuerzas) basándose en la simulación de cuerpos rígidos. Core Animation anima propiedades de CALayer (position, opacity, transform) según una curva temporal determinada. Dynamics es adecuado para física interactiva, Core Animation para transiciones predefinidas.
No hay soporte directo de UIKit Dynamics en SwiftUI. Para efectos físicos, usa UIKitView + UIDynamicAnimator dentro de UIViewRepresentable, o animaciones personalizadas mediante Animation.spring() y withAnimation() en SwiftUI.
Llama a animator.removeAllBehaviors() — esto elimina todos los comportamientos físicos activos. El animador se pausa automáticamente cuando todos los objetos alcanzan el reposo. Para una pausa temporal, usa la propiedad animator.isPaused o elimina comportamientos individuales.
Apple recomienda no más de 15-20 objetos con física completa (gravedad + colisiones + fuerzas). Para animaciones masivas, usa UIFieldBehavior — calcula las fuerzas de forma centralizada, sin colisiones por pares, lo que reduce la carga de la CPU.
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.
Lea también