UIKit Dynamics — рамка за физическа анимация в iOS (UIKit), която позволява на View да взаимодействат според законите на реалната физика: гравитация, сблъсъци, еластичност и сили на привличане. Статията обяснява компонентите на UIDynamicAnimator, видовете поведения (behavior) и практически сценарии за приложение.
Основни точки
UIKit Dynamics — рамка за физическо моделиране, представена от Apple в iOS 7 (2013). За разлика от UIView.animate (линейни преходи) и Core Animation (анимация на слоеве), UIKit Dynamics моделира реални физически взаимодействия: гравитация, сблъсъци, сили, еластичност и триене. Разработчикът добавя поведения (behaviors) към UIDynamicAnimator, а системата автоматично изчислява физиката за всеки кадър.
Рамката работи на 60/120 FPS и използва вграден физически двигател, базиран на симулация на твърди тела (rigid body simulation). UIKit Dynamics не изисква познания по физика или математика — достатъчно е да приложите готово поведение и да настроите параметрите.
Според Apple, UIKit Dynamics е подходящ за UI ефекти (анимация на купчина карти, „треперене“ на икони, физика на интерфейса), но не е предназначен за игри — за игри използвайте SceneKit или SpriteKit.
UIDynamicAnimator — централният клас на UIKit Dynamics. Инициализира се с reference view (обикновенно view на контролера) и управлява всички активни поведения. Всеки кадър UIDynamicAnimator преизчислява позициите, скоростите и ускоренията на всички добавени елементи съобразно законите на физиката.
Методът addBehavior добавя едно поведение (или сложно UIDynamicBehavior), removeBehavior — премахва. Animator автоматично спира, когато всички обекти достигнат състояние на покой (без сблъсъци и сили). Делегат методът — UIDynamicAnimatorDelegate — уведомява за пауза и подновяване на симулацията.
Всеки обект, участващ във физиката, трябва да имплементира протокола UIDynamicItem. UIView и UICollectionViewLayoutAttributes вече го имплементират. Протоколът изисква свойства: bounds, center, transform. Ако обектът е персонализиран — имплементирайте протокола ръчно.
UIKit Dynamics включва седем вградени вида поведения, всяко от които моделира определен физически ефект. Поведенията могат да се комбинират: например гравитация + сблъсъци + еластичност създават ефект на падащи и отскачащи обекти.
| Behavior | Физически ефект | Ключови параметри |
|---|---|---|
| UIGravityBehavior | Гравитация (вектор на сила) | gravityDirection (dx, dy), magnitude |
| UICollisionBehavior | Сблъсъци на обекти и граници | collisionMode, translucence, collisionDelegate |
| UIAttachmentBehavior | Връзка (пружина/кабел) | anchorPoint, length, damping, frequency |
| UISnapBehavior | Привличане към точка с амортизация | snapPoint, damping (0-1) |
| UIPushBehavior | Бутане/импулс (непрекъснат или моментален) | pushDirection, magnitude, mode |
| UIDynamicItemBehavior | Физически свойства на обект | elasticity, friction, density, resistance |
| UIFieldBehavior | Силови полета (вихър, магнит, радиус) | position, strength, falloff, region |
За реалистична физика на обект са необходими няколко поведения едновременно. Например за падаща карта: UIGravityBehavior (гравитационна сила), UICollisionBehavior (сблъсък с дъното), UIDynamicItemBehavior (elasticity: 0.4 за отскок). Всички поведения се добавят към един UIDynamicAnimator.
Swift кодът за UIKit Dynamics създава UIDynamicAnimator и добавя поведения. Примерът по-долу демонстрира гравитация с множество обекти, сблъсъци и персонализирани физически свойства.
import UIKit
class PhysicsViewController: UIViewController {
var animator: UIDynamicAnimator!
override func viewDidLoad() {
super.viewDidLoad()
// 1. Създаваме аниматор с reference view
animator = UIDynamicAnimator(referenceView: view)
// 2. Създаваме падащи обекти
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. Гравитация
let gravity = UIGravityBehavior(items: [redView, blueView])
gravity.gravityDirection = CGVector(dx: 0, dy: 1)
gravity.magnitude = 0.8
animator.addBehavior(gravity)
// 4. Сблъсъци
let collision = UICollisionBehavior(items: [redView, blueView])
collision.translatesReferenceBoundsIntoBoundary = true
collision.collisionDelegate = self
animator.addBehavior(collision)
// 5. Физически свойства
let itemBehavior = UIDynamicItemBehavior(items: [redView, blueView])
itemBehavior.elasticity = 0.6
itemBehavior.friction = 0.3
itemBehavior.density = 1.0
animator.addBehavior(itemBehavior)
// 6. Snap поведение при докосване
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap))
view.addGestureRecognizer(tap)
}
@objc
func handleTap(_ gesture: UITapGestureRecognizer) {
let point = gesture.location(in: view)
// Snap поведение за всеки обект
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("Сблъсък на: (point)")
}
}Примерът създава два View с гравитация, сблъсъци и физически свойства. UISnapBehavior при докосване привлича обектите към точката на докосване с амортизация 0.5. UICollisionBehaviorDelegate проследява началото на сблъсъци за звукови и визуални ефекти.
UIKit Dynamics се прилага в iOS приложения за не-игрова физика на интерфейса. Популярни сценарии: анимация на купчина карти (UISnapBehavior за привличане към центъра), разклащане на екрана при грешка (UIDynamicItemBehavior + UIPushBehavior), ефект на „падащи звезди“ в onboarding (gravity + collision + field behavior).
За производителност UIKit Dynamics препоръчва не повече от 15-20 едновременни обекта с физика. Всеки обект изисква изчисляване на сблъсъци и сили на всеки кадър. При превишаване на лимита използвайте CALayer вместо UIView — Core Animation обработва слоевете по-ефективно.
Често задавани въпроси
UIKit Dynamics моделира физически взаимодействия (гравитация, сблъсъци, сили) на базата на симулация на твърди тела. Core Animation — анимация на свойства на CALayer (position, opacity, transform) по зададена времева крива. Dynamics е подходящ за интерактивна физика, Core Animation — за предварително определени преходи.
Няма директна поддръжка на UIKit Dynamics в SwiftUI. За физически ефекти използвайте UIKitView + UIDynamicAnimator вътре в UIViewRepresentable или персонализирани анимации чрез Animation.spring() и withAnimation() в SwiftUI.
Извикайте animator.removeAllBehaviors() — това ще премахне всички активни физически поведения. Animator автоматично спира, когато всички обекти достигнат покой. За временна пауза използвайте свойството animator.isPaused или премахнете отделни поведения.
Apple препоръчва не повече от 15-20 обекта с пълна физика (гравитация + сблъсъци + сили). За масови анимации използвайте UIFieldBehavior — той изчислява силите централизирано без двойкови сблъсъци, което намалява натоварването на CPU.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също