UIkit Dynamics是UIkit的一套基于現(xiàn)實(shí)世界物理驅(qū)動(dòng)的一套交互體系,包含了我們常見的物理知識現(xiàn)象晤锥,如重力掉蔬、碰撞、彈力等效果矾瘾。而UIKit Dynamice提供了一整套逼真的物理動(dòng)作女轿,在實(shí)現(xiàn)一些逼真的物理效果的時(shí)事倍功半。
有四個(gè)概念我們來稍微描述一下:
- UIDynamicItem 就是物理體系可以影響到的物體壕翩,像現(xiàn)實(shí)世界的桌子蛉迹、椅子。在ios我們常見的UI控件像UIButton戈泼、UIView等實(shí)現(xiàn)了該接口婿禽。
- UIDynamicBehavior 一個(gè)行為,像重力或者彈性大猛、吸附等效果
- UIDynamicAnimator 一個(gè)動(dòng)畫執(zhí)行者扭倾,所有的行為都可以加入這個(gè)執(zhí)行者,重力+碰撞就可以模擬高空墜落拉挽绩!
- referenceView 參照體系膛壹,就像現(xiàn)實(shí)世界的參照物。
一、重力行為UIGravityBehavior
var animator : UIDynamicAnimator!
override func viewDidLoad() {
super.viewDidLoad()
//box
let box : UIView = UIView(frame: CGRectMake(135, 80, 50, 50))
box.backgroundColor = UIColor.grayColor()
self.view.backgroundColor = UIColor.whiteColor()
self.view.addSubview(box)
//參照物為背景view
self.animator = UIDynamicAnimator(referenceView: self.view)
//為box添加重力行為
let gravity = UIGravityBehavior(items: [box])
//執(zhí)行動(dòng)畫
self.animator.addBehavior(gravity)
}
這里注意把a(bǔ)nimator聲明為類的成員變量模聋,不然animator在viewDidLoad后就釋放內(nèi)存引用肩民,就沒有什么重力效果了。
GIF效果圖
我們可以設(shè)置重力的向量链方,大小和方向就是墜落的方向和下墜加速度了持痰。
<code>gravity.gravityDirection = CGVector(dx: 0, dy: 5)</code>
二、碰撞行為UICollisionBehavior
就這么無休止的墜落深淵未免也太無聊了吧,我們來讓那個(gè)它跟屏幕下方進(jìn)行碰撞。
var animator : UIDynamicAnimator!
override func viewDidLoad() {
super.viewDidLoad()
//box
let box : UIView = UIView(frame: CGRectMake(135, 80, 50, 50))
box.backgroundColor = UIColor.grayColor()
self.view.backgroundColor = UIColor.whiteColor()
self.view.addSubview(box)
//參照物為背景view
self.animator = UIDynamicAnimator(referenceView: self.view)
//為box添加重力行為
let gravity = UIGravityBehavior(items: [box])
//執(zhí)行動(dòng)畫
self.animator.addBehavior(gravity)
GIF效果圖
三辞嗡、連線行為UIAttachmentBehavior
連線就是兩個(gè)物體之間進(jìn)行連接或者一個(gè)物體跟一個(gè)錨點(diǎn)之間連接。
參數(shù)說明:UIAttachmentBehavior(item: offsetFromCenter: attachedToAnchor: )
item:物理體系可以影響到的物體
offsetFromCenter:物體中心偏移
-
attachedToAnchor:跟物體相連的錨點(diǎn)
var animator : UIDynamicAnimator! override func viewDidLoad() { super.viewDidLoad() animator = UIDynamicAnimator(referenceView: self.view) //靜止的box let staticBox = UIView(frame: CGRectMake(50, 50, 50, 50)) staticBox.backgroundColor = UIColor.redColor() staticBox.layer.cornerRadius = 5 ; //下墜的box let dynamicBox = UIView(frame: CGRectMake(250, 50, 50, 50)) dynamicBox.backgroundColor = UIColor.grayColor() dynamicBox.layer.cornerRadius = 5 ; //為dynamicBox添加重力行為 let cravity = UIGravityBehavior(items: [dynamicBox]) //為dynamicBox添加連線行為 let attachment = UIAttachmentBehavior(item: dynamicBox, offsetFromCenter: UIOffsetMake(0, 0), attachedToAnchor: CGPointMake(staticBox.center.x, staticBox.center.y)) //為dynamicBox添加碰撞行為 let collision = UICollisionBehavior(items: [dynamicBox]) collision.translatesReferenceBoundsIntoBoundary = true self.view.addSubview(staticBox) self.view.addSubview(dynamicBox) animator.addBehavior(cravity) animator.addBehavior(attachment) animator.addBehavior(collision) }
GIF效果圖
想讓“繩子”有彈性加上這段:<code>attachment.frequency = 1</code>
四珊佣、吸附行為UISnapBehavior
很有趣的“牛皮糖”效果
var animator : UIDynamicAnimator!
let tapGesture = UITapGestureRecognizer()
var box:UIView!
override func viewDidLoad() {
super.viewDidLoad()
//添加手勢,輕觸self.view,
self.tapGesture.addTarget(self, action: "tappedView")
self.view.userInteractionEnabled = true ;
self.view.addGestureRecognizer(tapGesture)
self.animator = UIDynamicAnimator(referenceView: self.view)
// Do any additional setup after loading the view, typically from a nib.
//物體
self.box = UIView(frame: CGRectMake(110, 50, 100, 100))
box.backgroundColor = UIColor.grayColor()
box.layer.cornerRadius = 5
self.view.addSubview(box)
}
//手勢回調(diào)方法
func tappedView(){
let point = self.tapGesture.locationInView(self.view)
self.animator.removeAllBehaviors()
let snap = UISnapBehavior(item: self.box, snapToPoint: point)
self.animator.addBehavior(snap)
}
GIF效果圖
四、推力UIPushBehavior
為物體施加一個(gè)外力淹仑,遵循力的合成
var box : UIView!
var animator : UIDynamicAnimator!
var push : UIPushBehavior!
let tapGetsture = UITapGestureRecognizer()
override func viewDidLoad() {
super.viewDidLoad()
self.animator = UIDynamicAnimator(referenceView: self.view)
//self.view加入輕觸手勢
self.tapGetsture.addTarget(self, action: "tappedView")
self.view.userInteractionEnabled = true
self.view.addGestureRecognizer(tapGetsture)
//box
self.box = UIView(frame: CGRectMake(110, 234, 100, 100))
self.box.layer.cornerRadius = 5 ;
self.box.backgroundColor = UIColor.grayColor()
//加入box
self.view.addSubview(self.box)
//碰撞
let collision = UICollisionBehavior(items: [box])
collision.setTranslatesReferenceBoundsIntoBoundaryWithInsets(UIEdgeInsets(top: self.topLayoutGuide.length, left: 0, bottom: self.bottomLayoutGuide.length, right: 0))
//推力
self.push = UIPushBehavior(items: [self.box], mode: UIPushBehaviorMode.Instantaneous)
self.push.angle = 0
self.push.magnitude = 0 ;
//加入行為
self.animator.addBehavior(self.push)
self.animator.addBehavior(collision)
}
//輕觸手勢
func tappedView(){
let tapPoint = self.tapGetsture.locationInView(self.view)
let centerPoint = CGPointMake(self.box.center.x, self.box.center.y)
//角度和大小
let angle = atan2(tapPoint.y - centerPoint.y, tapPoint.x - centerPoint.x)
var distance = sqrtf(powf(Float(tapPoint.x - centerPoint.x),2.0) + powf(Float(tapPoint.y - centerPoint.y),2))
distance = min(distance, 100.00)
self.push.setAngle(angle, magnitude: CGFloat(distance/100))
//每次更改push屬性時(shí),push都會(huì)變?yōu)椴豢苫顒?dòng)狀態(tài)肺孵,需要手動(dòng)更改active為true
self.push.active = true ;
}