UIKit Dynamics هو إطار عمل للرسوم المتحركة الفيزيائية في iOS (UIKit) يسمح للـ View بالتفاعل وفقًا لقوانين الفيزياء الحقيقية: الجاذبية والتصادمات والمرونة وقوى الجذب. تشرح المقالة مكونات UIDynamicAnimator وأنواع السلوكيات (behavior) وسيناريوهات الاستخدام العملية.
النقاط الرئيسية
UIKit Dynamics هو إطار عمل لمحاكاة الفيزياء قدمته Apple في iOS 7 (2013). على عكس UIView.animate (الانتقالات الخطية) وCore Animation (رسوم متحركة للطبقات)، يحاكي UIKit Dynamics التفاعلات الفيزيائية الحقيقية: الجاذبية والتصادمات والقوى والمرونة والاحتكاك. يضيف المطور سلوكيات إلى UIDynamicAnimator ويقوم النظام تلقائيًا بحساب الفيزياء لكل إطار.
يعمل الإطار بسرعة 60/120 إطارًا في الثانية ويستخدم محرك فيزياء مدمجًا يعتمد على محاكاة الأجسام الصلبة. لا يتطلب UIKit Dynamics معرفة بالفيزياء أو الرياضيات — فقط طبق سلوكًا جاهزًا واضبط معلماته.
وفقًا لـ Apple، UIKit Dynamics مناسب لتأثيرات واجهة المستخدم (رسوم متحركة لمجموعة بطاقات، اهتزاز الأيقونات، فيزياء الواجهة)، لكنه غير مخصص للألعاب — استخدم SceneKit أو SpriteKit للألعاب.
UIDynamicAnimator هو الفئة المركزية في UIKit Dynamics. تتم تهيئته مع reference view (عادةً view وحدة التحكم) ويدير جميع السلوكيات النشطة. في كل إطار، يعيد UIDynamicAnimator حساب المواضع والسرعات والتسارعات لجميع العناصر المضافة وفقًا للقوانين الفيزيائية.
طريقة addBehavior تضيف سلوكًا واحدًا (أو UIDynamicBehavior معقدًا)، removeBehavior تزيله. يتوقف المحرك تلقائيًا عندما تصل جميع الكائنات إلى حالة السكون (الاستمرار بدون تصادمات وقوى). طريقة المفوض — 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 (مرونة: 0.4 للارتداد). تضاف جميع السلوكيات إلى UIDynamicAnimator واحد.
كود Swift لـ UIKit Dynamics ينشئ UIDynamicAnimator ويضيف سلوكيات. المثال أدناه يوضح الجاذبية مع عدة كائنات وتصادمات وخصائص فيزيائية مخصصة.
import UIKit
class PhysicsViewController: UIViewController {
var animator: UIDynamicAnimator!
override func viewDidLoad() {
super.viewDidLoad()
// 1. إنشاء المحرك مع 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("تصادم في: (نقطة)")
}
}ينشئ المثال View مع جاذبية وتصادمات وخصائص فيزيائية. UISnapBehavior عند النقر يجذب الكائنات إلى نقطة اللمس بتخميد 0.5. يتتبع UICollisionBehaviorDelegate بداية التصادمات للتأثيرات الصوتية والمرئية.
UIKit Dynamics يستخدم في تطبيقات iOS لفيزياء الواجهة غير المخصصة للألعاب. السيناريوهات الشائعة: رسوم متحركة لمجموعة بطاقات (UISnapBehavior للجذب إلى المركز)، اهتزاز الشاشة عند الخطأ (UIDynamicItemBehavior + UIPushBehavior)، تأثير "النجوم المتساقطة" في الترحيب (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.isPaused أو أزل السلوكيات الفردية.
توصي Apple بعدم تجاوز 15-20 كائنًا مع فيزياء كاملة (جاذبية + تصادمات + قوى). للرسوم المتحركة الجماعية، استخدم UIFieldBehavior — يحسب القوى مركزياً دون تصادمات زوجية، مما يقلل حمل المعالج.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا