最近發現一個 iOS 7 就出現的好玩意 - UIDynamicAnimator,做出一個搖骰子的動畫就變成非常簡單
首先:先宣告一個 UIDynamicAnimator ,並告訴它要作動的畫面在哪裏
let dynamicAnimator = UIDynamicAnimator(referenceView: self.view)
接下來就是告訴它這個動畫裡面要包含哪些元素跟哪些物件要做這些動畫。
重力
//什麼是 UIDynamicItem?簡單來說就是所有繼承 UIView 的 UI 物件通通都是 UIDynamicItem
let items:[UIDynamicItem] = ...
let gravite = UIGravityBehavior(items: items)
gravite.gravityDirection:CGVector = CGVector(dx: 0.0, dy: 1.0) //重力方向
//(0.0, 1.0) ↓
//(1.0, 0.0) →
//(-1.0, 0.0) ←
//(0.0, -1.0) ↑
//(-1.0, -1.0) ↖︎
//(1.0, -1.0) ↗︎
//(-1.0, 1.0) ↙︎
//(1.0, 1.0) ↘︎
gravite.angle = aDegree * 90 //重力方向,以弧度表示 (let aDegree = CGFloat.pi / 180)
gravite.magnitude = 10 //重力大小,數值越大,掉落速度越快
gravite.setAngle(aDegree * 90, magnitude: 10) //跟上面的是一樣的
dynamicAnimator.addBehavior(gravite) //把這個行為加入 UIDynamicAnimator 裡面
碰撞
//所有的物體都會有碰撞的物理現象,差別在於物體碰撞後的結果是什麼。
let collisionBehavior = UICollisionBehavior(items: items) //需要發生碰撞的元件是哪裡
collisionBehavior.translatesReferenceBoundsIntoBoundary = true //用參考視圖邊界作為碰撞邊界,也就是剛剛的 referenceView 當作碰撞的邊界
collisionBehavior.collisionMode = .everything //有三種模式:items > 物體間的碰撞,boundaries > 邊界的碰撞,everything > 所有的碰撞
collisionBehavior.collisionDelegate = self //碰撞有自己的協定可以實作
dynamicAnimator.addBehavior(collisionBehavior) //把這個行為加入 UIDynamicAnimator 裡面
物體屬性行為
let litterBehavior = UIDynamicItemBehavior(items: items)
litterBehavior.elasticity = 0.8 //物體的彈性係數,通常介於 0 - 1 之間
litterBehavior.density = 1 //物體密度,計算物體總質量,質量越大的物體加減速越難
litterBehavior.friction = 0.01 //摩擦係數,決定接觸面與光滑面的摩擦力有多大
litterBehavior.resistance = 0.05 //阻力
litterBehavior.angularResistance = 0.2 //旋轉阻力,旋轉時的阻力有多大
litterBehavior.allowsRotation = true // 物體是否可以選轉
litterBehavior.isAnchored = true //定錨效果:該物件參與碰撞,但不受碰撞影響
dynamicAnimator.addBehavior(litterBehavior)
加速度
let push = UIPushBehavior(items: items, mode: .instantaneous) //mode 有分兩種:持續性(continuous)或是爆發性(instantaneous)
push.active = true
push.setAngle(pointToAngle(p: CGPoint(x: 50, y: -300)), magnitude: 10)//推的角度跟速度
dynamicAnimator.addBehavior(push)
透過上述一系列的參數設定之後就可以做出骰骰子的動畫囉。