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 بهطور خودکار وقتی همه اشیاء به حالت سکون میرسند (بدون برخورد و نیرو) متوقف میشود. متد delegate — 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. ایجاد animator با 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)، اثر «ستارههای در حال سقوط» در آموزش (gravity + collision + field behavior).
برای عملکرد، UIKit Dynamics بیش از 15-20 شیء همزمان با فیزیک را توصیه نمیکند. هر شیء نیاز به محاسبه برخوردها و نیروها در هر فریم دارد. در صورت تجاوز از حد، به جای UIView از CALayer استفاده کنید — 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 از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید