UIKit Dynamics — framework fizycznej animacji w iOS (UIKit), pozwalający View oddziaływać według praw rzeczywistej fizyki: grawitacja, kolizje, sprężystość i siły przyciągania. Artykuł wyjaśnia komponenty UIDynamicAnimator, rodzaje zachowań (behavior) i praktyczne scenariusze zastosowania.
Najważniejsze
UIKit Dynamics — framework modelowania fizycznego, wprowadzony przez Apple w iOS 7 (2013). W przeciwieństwie do UIView.animate (przejścia liniowe) i Core Animation (animacja warstw), UIKit Dynamics modeluje rzeczywiste interakcje fizyczne: grawitację, kolizje, siły, sprężystość i tarcie. Deweloper dodaje zachowania (behaviors) do UIDynamicAnimator, a system automatycznie oblicza fizykę dla każdej klatki.
Framework działa z częstotliwością 60/120 FPS i wykorzystuje wbudowany silnik fizyczny oparty na symulacji brył sztywnych (rigid body simulation). UIKit Dynamics nie wymaga znajomości fizyki ani matematyki — wystarczy zastosować gotowe zachowanie i skonfigurować parametry.
Według Apple, UIKit Dynamics nadaje się do efektów UI (animacja stosu kart, „drżenie” ikon, fizyka interfejsu), ale nie jest przeznaczony do gier — do gier używaj SceneKit lub SpriteKit.
UIDynamicAnimator — główna klasa UIKit Dynamics. Inicjalizuje się z reference view (zwykle view kontrolera) i zarządza wszystkimi aktywnymi zachowaniami. Każdą klatkę UIDynamicAnimator przelicza pozycje, prędkości i przyspieszenia wszystkich dodanych elementów z uwzględnieniem praw fizyki.
Metoda addBehavior dodaje jedno zachowanie (lub złożone UIDynamicBehavior), removeBehavior — usuwa. Animator automatycznie wstrzymuje się, gdy wszystkie obiekty osiągną stan spoczynku (bez kolizji i sił). Metoda delegate — UIDynamicAnimatorDelegate — powiadamia o pauzie i wznowieniu symulacji.
Każdy obiekt uczestniczący w fizyce musi implementować protokół UIDynamicItem. UIView i UICollectionViewLayoutAttributes już go implementują. Protokół wymaga właściwości: bounds, center, transform. Jeśli obiekt jest niestandardowy — zaimplementuj protokół ręcznie.
UIKit Dynamics zawiera siedem wbudowanych typów zachowań, z których każde modeluje określony efekt fizyczny. Zachowania można łączyć: na przykład grawitacja + kolizje + sprężystość tworzą efekt spadających i odbijających się obiektów.
| Behavior | Efekt fizyczny | Kluczowe parametry |
|---|---|---|
| UIGravityBehavior | Grawitacja (wektor siły) | gravityDirection (dx, dy), magnitude |
| UICollisionBehavior | Kolizje obiektów i granic | collisionMode, translucence, collisionDelegate |
| UIAttachmentBehavior | Połączenie (sprężyna/lina) | anchorPoint, length, damping, frequency |
| UISnapBehavior | Przyciąganie do punktu z tłumieniem | snapPoint, damping (0-1) |
| UIPushBehavior | Pchnięcie/impuls (ciągły lub natychmiastowy) | pushDirection, magnitude, mode |
| UIDynamicItemBehavior | Właściwości fizyczne obiektu | elasticity, friction, density, resistance |
| UIFieldBehavior | Pola siłowe (wir, magnes, promień) | position, strength, falloff, region |
Do realistycznej fizyki obiektu potrzeba kilku zachowań jednocześnie. Na przykład dla spadającej karty: UIGravityBehavior (siła ciężkości), UICollisionBehavior (kolizja z dnem), UIDynamicItemBehavior (elasticity: 0.4 dla odbicia). Wszystkie zachowania są dodawane do jednego UIDynamicAnimator.
Swift kod dla UIKit Dynamics tworzy UIDynamicAnimator i dodaje zachowania. Poniższy przykład demonstruje grawitację z wieloma obiektami, kolizjami i niestandardowymi właściwościami fizycznymi.
import UIKit
class PhysicsViewController: UIViewController {
var animator: UIDynamicAnimator!
override func viewDidLoad() {
super.viewDidLoad()
// 1. Tworzymy animator z reference view
animator = UIDynamicAnimator(referenceView: view)
// 2. Tworzymy spadające obiekty
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. Grawitacja
let gravity = UIGravityBehavior(items: [redView, blueView])
gravity.gravityDirection = CGVector(dx: 0, dy: 1)
gravity.magnitude = 0.8
animator.addBehavior(gravity)
// 4. Kolizje
let collision = UICollisionBehavior(items: [redView, blueView])
collision.translatesReferenceBoundsIntoBoundary = true
collision.collisionDelegate = self
animator.addBehavior(collision)
// 5. Właściwości fizyczne
let itemBehavior = UIDynamicItemBehavior(items: [redView, blueView])
itemBehavior.elasticity = 0.6
itemBehavior.friction = 0.3
itemBehavior.density = 1.0
animator.addBehavior(itemBehavior)
// 6. Zachowanie Snap po dotknięciu
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap))
view.addGestureRecognizer(tap)
}
@objc
func handleTap(_ gesture: UITapGestureRecognizer) {
let point = gesture.location(in: view)
// Zachowanie Snap dla każdego obiektu
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("Kolizja w: (point)")
}
}Przykład tworzy dwa View z grawitacją, kolizjami i właściwościami fizycznymi. UISnapBehavior po dotknięciu przyciąga obiekty do punktu dotknięcia z tłumieniem 0.5. UICollisionBehaviorDelegate śledzi rozpoczęcie kolizji dla efektów dźwiękowych i wizualnych.
UIKit Dynamics jest stosowany w aplikacjach iOS do niegrywalnej fizyki interfejsu. Popularne scenariusze: animacja stosu kart (UISnapBehavior do przyciągania do środka), potrząsanie ekranem przy błędzie (UIDynamicItemBehavior + UIPushBehavior), efekt „spadających gwiazd” w onboardingu (gravity + collision + field behavior).
Dla wydajności UIKit Dynamics zaleca się nie więcej niż 15-20 jednoczesnych obiektów z fizyką. Każdy obiekt wymaga obliczania kolizji i sił w każdej klatce. Przy przekroczeniu limitu używaj CALayer zamiast UIView — Core Animation przetwarza warstwy efektywniej.
Często zadawane pytania
UIKit Dynamics modeluje interakcje fizyczne (grawitacja, kolizje, siły) w oparciu o symulację brył sztywnych. Core Animation — animacja właściwości CALayer (position, opacity, transform) według zadanej krzywej czasowej. Dynamics nadaje się do interaktywnej fizyki, Core Animation — do predefiniowanych przejść.
Bezpośredniego wsparcia UIKit Dynamics w SwiftUI nie ma. Do efektów fizycznych używaj UIKitView + UIDynamicAnimator wewnątrz UIViewRepresentable lub niestandardowych animacji przez Animation.spring() i withAnimation() w SwiftUI.
Wywołaj animator.removeAllBehaviors() — to usunie wszystkie aktywne zachowania fizyczne. Animator automatycznie wstrzymuje się, gdy wszystkie obiekty osiągną spoczynek. Do tymczasowej pauzy użyj właściwości animator.isPaused lub usuń poszczególne zachowania.
Apple zaleca nie więcej niż 15-20 obiektów z pełną fizyką (grawitacja + kolizje + siły). Do masowych animacji używaj UIFieldBehavior — oblicza on siły centralnie, bez par kolizyjnych, co zmniejsza obciążenie CPU.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również