UIKit Dynamics là framework hoạt ảnh vật lý trong iOS (UIKit) cho phép các View tương tác theo các định luật vật lý thực tế: trọng lực, va chạm, độ đàn hồi và lực hút. Bài viết này giải thích các thành phần của UIDynamicAnimator, các loại hành vi (behavior) và các kịch bản sử dụng thực tế.
Những điểm chính
UIKit Dynamics là framework mô phỏng vật lý được Apple giới thiệu trong iOS 7 (2013). Không giống như UIView.animate (chuyển đổi tuyến tính) và Core Animation (hoạt ảnh lớp), UIKit Dynamics mô phỏng các tương tác vật lý thực tế: trọng lực, va chạm, lực, độ đàn hồi và ma sát. Nhà phát triển thêm các hành vi vào UIDynamicAnimator và hệ thống tự động tính toán vật lý cho mỗi khung hình.
Framework chạy ở 60/120 FPS và sử dụng công cụ vật lý tích hợp dựa trên mô phỏng vật thể rắn. UIKit Dynamics không yêu cầu kiến thức về vật lý hay toán học — chỉ cần áp dụng một hành vi có sẵn và cấu hình tham số của nó.
Theo Apple, UIKit Dynamics phù hợp cho các hiệu ứng UI (hoạt ảnh xấp thẻ, rung biểu tượng, vật lý giao diện), nhưng không dành cho trò chơi — hãy sử dụng SceneKit hoặc SpriteKit cho trò chơi.
UIDynamicAnimator là lớp trung tâm của UIKit Dynamics. Nó được khởi tạo với reference view (thường là view của bộ điều khiển) và quản lý tất cả các hành vi đang hoạt động. Mỗi khung hình UIDynamicAnimator tính toán lại vị trí, vận tốc và gia tốc của tất cả các phần tử được thêm vào theo các định luật vật lý.
Phương thức addBehavior thêm một hành vi (hoặc UIDynamicBehavior phức tạp), removeBehavior xóa nó. Bộ hoạt ảnh tự động tạm dừng khi tất cả các đối tượng đạt đến trạng thái nghỉ (tiếp tục không có va chạm và lực). Phương thức ủy quyền — UIDynamicAnimatorDelegate — thông báo về việc tạm dừng và tiếp tục mô phỏng.
Bất kỳ đối tượng nào tham gia vào vật lý đều phải triển khai giao thức UIDynamicItem. UIView và UICollectionViewLayoutAttributes đã triển khai nó. Giao thức yêu cầu các thuộc tính: bounds, center, transform. Nếu đối tượng tùy chỉnh — hãy triển khai giao thức thủ công.
UIKit Dynamics bao gồm bảy loại hành vi tích hợp, mỗi loại mô hình hóa một hiệu ứng vật lý cụ thể. Các hành vi có thể được kết hợp: ví dụ, trọng lực + va chạm + độ đàn hồi tạo ra hiệu ứng các vật thể rơi và nảy.
| Behavior | Hiệu ứng vật lý | Tham số chính |
|---|---|---|
| UIGravityBehavior | Trọng lực (vector lực) | gravityDirection (dx, dy), magnitude |
| UICollisionBehavior | Va chạm vật thể và ranh giới | collisionMode, translucence, collisionDelegate |
| UIAttachmentBehavior | Kết nối (lò xo/dây cáp) | anchorPoint, length, damping, frequency |
| UISnapBehavior | Hút về điểm có giảm chấn | snapPoint, damping (0-1) |
| UIPushBehavior | Đẩy/xung lực (liên tục hoặc tức thời) | pushDirection, magnitude, mode |
| UIDynamicItemBehavior | Thuộc tính vật lý của đối tượng | elasticity, friction, density, resistance |
| UIFieldBehavior | Trường lực (xoáy, từ tính, xuyên tâm) | position, strength, falloff, region |
Để có vật lý đối tượng chân thực, cần nhiều hành vi đồng thời. Ví dụ, cho một lá bài rơi: UIGravityBehavior (lực hấp dẫn), UICollisionBehavior (va chạm với đáy), UIDynamicItemBehavior (độ đàn hồi: 0.4 để nảy). Tất cả các hành vi được thêm vào một UIDynamicAnimator duy nhất.
Mã Swift cho UIKit Dynamics tạo UIDynamicAnimator và thêm các hành vi. Ví dụ dưới đây minh họa trọng lực với nhiều đối tượng, va chạm và thuộc tính vật lý tùy chỉnh.
import UIKit
class PhysicsViewController: UIViewController {
var animator: UIDynamicAnimator!
override func viewDidLoad() {
super.viewDidLoad()
// 1. Tạo bộ hoạt ảnh với reference view
animator = UIDynamicAnimator(referenceView: view)
// 2. Tạo các đối tượng rơi
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. Trọng lực
let gravity = UIGravityBehavior(items: [redView, blueView])
gravity.gravityDirection = CGVector(dx: 0, dy: 1)
gravity.magnitude = 0.8
animator.addBehavior(gravity)
// 4. Va chạm
let collision = UICollisionBehavior(items: [redView, blueView])
collision.translatesReferenceBoundsIntoBoundary = true
collision.collisionDelegate = self
animator.addBehavior(collision)
// 5. Thuộc tính vật lý
let itemBehavior = UIDynamicItemBehavior(items: [redView, blueView])
itemBehavior.elasticity = 0.6
itemBehavior.friction = 0.3
itemBehavior.density = 1.0
animator.addBehavior(itemBehavior)
// 6. Hành vi Snap khi chạm
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap))
view.addGestureRecognizer(tap)
}
@objc
func handleTap(_ gesture: UITapGestureRecognizer) {
let point = gesture.location(in: view)
// Hành vi Snap cho mỗi đối tượng
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("Va chạm tại: (điểm)")
}
}Ví dụ tạo hai View với trọng lực, va chạm và thuộc tính vật lý. UISnapBehavior khi chạm hút các đối tượng đến điểm chạm với giảm chấn 0.5. UICollisionBehaviorDelegate theo dõi sự bắt đầu va chạm để tạo hiệu ứng âm thanh và hình ảnh.
UIKit Dynamics được sử dụng trong các ứng dụng iOS cho vật lý giao diện không phải trò chơi. Các kịch bản phổ biến: hoạt ảnh xấp thẻ (UISnapBehavior để hút về trung tâm), lắc màn hình khi lỗi (UIDynamicItemBehavior + UIPushBehavior), hiệu ứng "sao băng" trong giới thiệu (gravity + collision + field behavior).
Về hiệu suất, UIKit Dynamics khuyến nghị không quá 15-20 đối tượng đồng thời có vật lý. Mỗi đối tượng yêu cầu tính toán va chạm và lực mỗi khung hình. Khi vượt quá giới hạn, hãy sử dụng CALayer thay vì UIView — Core Animation xử lý các lớp hiệu quả hơn.
Các câu hỏi thường gặp
UIKit Dynamics mô hình hóa các tương tác vật lý (trọng lực, va chạm, lực) dựa trên mô phỏng vật thể rắn. Core Animation tạo hoạt ảnh cho các thuộc tính CALayer (position, opacity, transform) theo một đường cong thời gian xác định. Dynamics phù hợp cho vật lý tương tác, Core Animation cho các chuyển đổi được xác định trước.
Không có hỗ trợ trực tiếp cho UIKit Dynamics trong SwiftUI. Để có hiệu ứng vật lý, hãy sử dụng UIKitView + UIDynamicAnimator bên trong UIViewRepresentable, hoặc hoạt ảnh tùy chỉnh qua Animation.spring() và withAnimation() trong SwiftUI.
Gọi animator.removeAllBehaviors() — thao tác này xóa tất cả các hành vi vật lý đang hoạt động. Bộ hoạt ảnh tự động tạm dừng khi tất cả các đối tượng đạt đến trạng thái nghỉ. Để tạm dừng tạm thời, hãy sử dụng thuộc tính animator.isPaused hoặc xóa các hành vi riêng lẻ.
Apple khuyến nghị không quá 15-20 đối tượng với vật lý đầy đủ (trọng lực + va chạm + lực). Đối với hoạt ảnh số lượng lớn, hãy sử dụng UIFieldBehavior — nó tính toán lực tập trung, không cần va chạm theo cặp, giảm tải CPU.
Tóm tắt
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm