UIKit Dynamics è un framework di animazione fisica in iOS (UIKit) che consente alle Views di interagire secondo le leggi della fisica reale: gravità, collisioni, elasticità e forze di attrazione. Questo articolo spiega i componenti di UIDynamicAnimator, i tipi di comportamenti (behavior) e gli scenari pratici di utilizzo.
Punti chiave
UIKit Dynamics è un framework di simulazione fisica introdotto da Apple in iOS 7 (2013). A differenza di UIView.animate (transizioni lineari) e Core Animation (animazione di layer), UIKit Dynamics simula interazioni fisiche reali: gravità, collisioni, forze, elasticità e attrito. Lo sviluppatore aggiunge comportamenti a UIDynamicAnimator e il sistema calcola automaticamente la fisica per ogni fotogramma.
Il framework funziona a 60/120 FPS e utilizza un motore fisico integrato basato sulla simulazione di corpi rigidi. UIKit Dynamics non richiede conoscenze di fisica o matematica — basta applicare un comportamento già pronto e configurare i suoi parametri.
Secondo Apple, UIKit Dynamics è adatto per effetti UI (animazione di pile di carte, vibrazione di icone, fisica dell'interfaccia), ma non è destinato ai giochi — per i giochi usa SceneKit o SpriteKit.
UIDynamicAnimator è la classe centrale di UIKit Dynamics. Viene inizializzato con una reference view (di solito la view del controllore) e gestisce tutti i comportamenti attivi. Ogni fotogramma UIDynamicAnimator ricalcola posizioni, velocità e accelerazioni di tutti gli elementi aggiunti secondo le leggi fisiche.
Il metodo addBehavior aggiunge un comportamento (o un UIDynamicBehavior complesso), removeBehavior lo rimuove. L'animatore si mette in pausa automaticamente quando tutti gli oggetti raggiungono uno stato di riposo (continuano senza collisioni e forze). Il metodo delegato — UIDynamicAnimatorDelegate — notifica la pausa e la ripresa della simulazione.
Qualsiasi oggetto che partecipa alla fisica deve implementare il protocollo UIDynamicItem. UIView e UICollectionViewLayoutAttributes lo implementano già. Il protocollo richiede le proprietà: bounds, center, transform. Se l'oggetto è personalizzato — implementa il protocollo manualmente.
UIKit Dynamics include sette tipi di comportamenti incorporati, ciascuno modella un effetto fisico specifico. I comportamenti possono essere combinati: ad esempio, gravità + collisioni + elasticità creano l'effetto di oggetti che cadono e rimbalzano.
| Behavior | Effetto fisico | Parametri chiave |
|---|---|---|
| UIGravityBehavior | Gravità (vettore di forza) | gravityDirection (dx, dy), magnitude |
| UICollisionBehavior | Collisioni di oggetti e confini | collisionMode, translucence, collisionDelegate |
| UIAttachmentBehavior | Connessione (molla/cavo) | anchorPoint, length, damping, frequency |
| UISnapBehavior | Attrazione a punto con smorzamento | snapPoint, damping (0-1) |
| UIPushBehavior | Spinta/impulso (continuo o istantaneo) | pushDirection, magnitude, mode |
| UIDynamicItemBehavior | Proprietà fisiche dell'oggetto | elasticity, friction, density, resistance |
| UIFieldBehavior | Campi di forza (vortice, magnetico, radiale) | position, strength, falloff, region |
Per una fisica realistica degli oggetti, sono necessari più comportamenti contemporaneamente. Ad esempio, per una carta che cade: UIGravityBehavior (forza di gravità), UICollisionBehavior (collisione con il fondo), UIDynamicItemBehavior (elasticità: 0,4 per il rimbalzo). Tutti i comportamenti vengono aggiunti a un unico UIDynamicAnimator.
Il codice Swift per UIKit Dynamics crea un UIDynamicAnimator e aggiunge comportamenti. L'esempio seguente dimostra la gravità con più oggetti, collisioni e proprietà fisiche personalizzate.
import UIKit
class PhysicsViewController: UIViewController {
var animator: UIDynamicAnimator!
override func viewDidLoad() {
super.viewDidLoad()
// 1. Creare animatore con reference view
animator = UIDynamicAnimator(referenceView: view)
// 2. Creare oggetti in caduta
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. Gravità
let gravity = UIGravityBehavior(items: [redView, blueView])
gravity.gravityDirection = CGVector(dx: 0, dy: 1)
gravity.magnitude = 0.8
animator.addBehavior(gravity)
// 4. Collisioni
let collision = UICollisionBehavior(items: [redView, blueView])
collision.translatesReferenceBoundsIntoBoundary = true
collision.collisionDelegate = self
animator.addBehavior(collision)
// 5. Proprietà fisiche
let itemBehavior = UIDynamicItemBehavior(items: [redView, blueView])
itemBehavior.elasticity = 0.6
itemBehavior.friction = 0.3
itemBehavior.density = 1.0
animator.addBehavior(itemBehavior)
// 6. Comportamento Snap al tocco
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap))
view.addGestureRecognizer(tap)
}
@objc
func handleTap(_ gesture: UITapGestureRecognizer) {
let point = gesture.location(in: view)
// Comportamento Snap per ogni oggetto
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("Collisione a: (punto)")
}
}L'esempio crea due Views con gravità, collisioni e proprietà fisiche. UISnapBehavior al tocco attira gli oggetti al punto di contatto con smorzamento 0,5. UICollisionBehaviorDelegate traccia l'inizio delle collisioni per effetti sonori e visivi.
UIKit Dynamics viene utilizzato nelle applicazioni iOS per la fisica dell'interfaccia non legata ai giochi. Scenari popolari: animazione di pile di carte (UISnapBehavior per l'attrazione al centro), scossone dello schermo in caso di errore (UIDynamicItemBehavior + UIPushBehavior), effetto "stelle cadenti" nell'onboarding (gravity + collision + field behavior).
Per le prestazioni, UIKit Dynamics consiglia non più di 15-20 oggetti simultanei con fisica. Ogni oggetto richiede calcoli di collisione e forza per ogni fotogramma. Se il limite viene superato, utilizza CALayer invece di UIView — Core Animation gestisce i layer in modo più efficiente.
Domande frequenti
UIKit Dynamics modella interazioni fisiche (gravità, collisioni, forze) basate sulla simulazione di corpi rigidi. Core Animation anima le proprietà di CALayer (position, opacity, transform) lungo una curva temporale specificata. Dynamics è adatto per la fisica interattiva, Core Animation per transizioni predefinite.
Non c'è supporto diretto per UIKit Dynamics in SwiftUI. Per effetti fisici, utilizza UIKitView + UIDynamicAnimator all'interno di UIViewRepresentable, o animazioni personalizzate tramite Animation.spring() e withAnimation() in SwiftUI.
Chiama animator.removeAllBehaviors() — questo rimuove tutti i comportamenti fisici attivi. L'animatore si mette in pausa automaticamente quando tutti gli oggetti raggiungono il riposo. Per una pausa temporanea, usa la proprietà animator.isPaused o rimuovi i comportamenti individuali.
Apple consiglia non più di 15-20 oggetti con fisica completa (gravità + collisioni + forze). Per animazioni di massa, usa UIFieldBehavior — calcola le forze centralmente, senza collisioni a coppie, riducendo il carico della CPU.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche