UIKit Dynamics é um framework de animação física no iOS (UIKit) que permite que Views interajam de acordo com as leis da física real: gravidade, colisões, elasticidade e forças de atração. Este artigo explica os componentes do UIDynamicAnimator, os tipos de comportamentos (behavior) e cenários práticos de uso.
Pontos principais
UIKit Dynamics é um framework de simulação física introduzido pela Apple no iOS 7 (2013). Ao contrário de UIView.animate (transições lineares) e Core Animation (animação de camadas), UIKit Dynamics simula interações físicas reais: gravidade, colisões, forças, elasticidade e atrito. O desenvolvedor adiciona comportamentos ao UIDynamicAnimator e o sistema calcula automaticamente a física para cada quadro.
O framework funciona a 60/120 FPS e usa um motor físico integrado baseado em simulação de corpos rígidos. UIKit Dynamics não requer conhecimento de física ou matemática — basta aplicar um comportamento pronto e configurar seus parâmetros.
De acordo com a Apple, UIKit Dynamics é adequado para efeitos de UI (animação de pilha de cartas, vibração de ícones, física de interface), mas não se destina a jogos — para jogos use SceneKit ou SpriteKit.
UIDynamicAnimator é a classe central do UIKit Dynamics. Ele é inicializado com uma reference view (geralmente a view do controlador) e gerencia todos os comportamentos ativos. A cada quadro, o UIDynamicAnimator recalcula posições, velocidades e acelerações de todos os elementos adicionados de acordo com as leis físicas.
O método addBehavior adiciona um comportamento (ou um UIDynamicBehavior complexo), removeBehavior remove. O animador pausa automaticamente quando todos os objetos atingem um estado de repouso (continuam sem colisões e forças). O método delegado — UIDynamicAnimatorDelegate — notifica sobre pausa e retomada da simulação.
Qualquer objeto que participe da física deve implementar o protocolo UIDynamicItem. UIView e UICollectionViewLayoutAttributes já o implementam. O protocolo requer as propriedades: bounds, center, transform. Se o objeto for personalizado — implemente o protocolo manualmente.
UIKit Dynamics inclui sete tipos de comportamentos incorporados, cada um modelando um efeito físico específico. Os comportamentos podem ser combinados: por exemplo, gravidade + colisões + elasticidade criam o efeito de objetos caindo e quicando.
| Behavior | Efeito físico | Parâmetros principais |
|---|---|---|
| UIGravityBehavior | Gravidade (vetor de força) | gravityDirection (dx, dy), magnitude |
| UICollisionBehavior | Colisões de objetos e limites | collisionMode, translucence, collisionDelegate |
| UIAttachmentBehavior | Conexão (mola/cabo) | anchorPoint, length, damping, frequency |
| UISnapBehavior | Atração para ponto com amortecimento | snapPoint, damping (0-1) |
| UIPushBehavior | Empurrão/impulso (contínuo ou instantâneo) | pushDirection, magnitude, mode |
| UIDynamicItemBehavior | Propriedades físicas do objeto | elasticity, friction, density, resistance |
| UIFieldBehavior | Campos de força (vórtice, magnético, radial) | position, strength, falloff, region |
Para física realista de objetos, vários comportamentos são necessários simultaneamente. Por exemplo, para uma carta caindo: UIGravityBehavior (força da gravidade), UICollisionBehavior (colisão com o fundo), UIDynamicItemBehavior (elasticidade: 0.4 para quique). Todos os comportamentos são adicionados a um único UIDynamicAnimator.
O código Swift para UIKit Dynamics cria um UIDynamicAnimator e adiciona comportamentos. O exemplo abaixo demonstra gravidade com múltiplos objetos, colisões e propriedades físicas personalizadas.
import UIKit
class PhysicsViewController: UIViewController {
var animator: UIDynamicAnimator!
override func viewDidLoad() {
super.viewDidLoad()
// 1. Criar animador com view de referência
animator = UIDynamicAnimator(referenceView: view)
// 2. Criar objetos em queda
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. Gravidade
let gravity = UIGravityBehavior(items: [redView, blueView])
gravity.gravityDirection = CGVector(dx: 0, dy: 1)
gravity.magnitude = 0.8
animator.addBehavior(gravity)
// 4. Colisões
let collision = UICollisionBehavior(items: [redView, blueView])
collision.translatesReferenceBoundsIntoBoundary = true
collision.collisionDelegate = self
animator.addBehavior(collision)
// 5. Propriedades físicas
let itemBehavior = UIDynamicItemBehavior(items: [redView, blueView])
itemBehavior.elasticity = 0.6
itemBehavior.friction = 0.3
itemBehavior.density = 1.0
animator.addBehavior(itemBehavior)
// 6. Comportamento Snap ao toque
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap))
view.addGestureRecognizer(tap)
}
@objc
func handleTap(_ gesture: UITapGestureRecognizer) {
let point = gesture.location(in: view)
// Comportamento 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("Colisão em: (ponto)")
}
}O exemplo cria duas Views com gravidade, colisões e propriedades físicas. UISnapBehavior ao toque atrai objetos para o ponto de toque com amortecimento de 0,5. UICollisionBehaviorDelegate rastreia o início de colisões para efeitos sonoros e visuais.
UIKit Dynamics é usado em aplicações iOS para física de interface não relacionada a jogos. Cenários populares: animação de pilha de cartas (UISnapBehavior para atração ao centro), vibração de tela em erro (UIDynamicItemBehavior + UIPushBehavior), efeito de "estrelas cadentes" em onboarding (gravity + collision + field behavior).
Para desempenho, UIKit Dynamics recomenda não mais de 15-20 objetos simultâneos com física. Cada objeto requer cálculos de colisão e força a cada quadro. Se o limite for excedido, use CALayer em vez de UIView — Core Animation processa camadas de forma mais eficiente.
Perguntas frequentes
UIKit Dynamics modela interações físicas (gravidade, colisões, forças) com base em simulação de corpos rígidos. Core Animation anima propriedades do CALayer (position, opacity, transform) ao longo de uma curva temporal especificada. Dynamics é adequado para física interativa, Core Animation para transições predefinidas.
Não há suporte direto para UIKit Dynamics no SwiftUI. Para efeitos físicos, use UIKitView + UIDynamicAnimator dentro de UIViewRepresentable, ou animações personalizadas via Animation.spring() e withAnimation() no SwiftUI.
Chame animator.removeAllBehaviors() — isso remove todos os comportamentos físicos ativos. O animador pausa automaticamente quando todos os objetos atingem o repouso. Para pausa temporária, use a propriedade animator.isPaused ou remova comportamentos individuais.
A Apple recomenda não mais que 15-20 objetos com física completa (gravidade + colisões + forças). Para animações em massa, use UIFieldBehavior — ele calcula forças centralmente, sem colisões pareadas, reduzindo a carga da CPU.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também