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), εφέ «πεφτόντων αστεριών» στο 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. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης