[ SWIFT ] - 史丹福 StandFord-CS193P-課程12-心得分享-20150903
[ SWIFT ] - 史丹福 StandFord-CS193P-課程12-心得分享-20150903
課程重點:
Physics based Dynamic Animation-物理動態動畫教學
Demo:打磚塊遊戲
1.Dynamic Animation
介紹:物理動畫與一般動畫不同在於,物理動畫指的是view上的物件,而一般動畫指的是整個view的動作。
2.使用物理動畫的步驟:
2.1建置一個UIDynamicAnimator
2.2加入UIDynamicAnimatorBehavios:增加動態行為,例如:加入重力或碰撞的效果
2.3加入UIDynamicItems:設置受影響的對象。
※將物理動畫效果設置在主View上,其SubView也會有相同效果。
程式範例:
(a)透過.addBehavior設置動畫行為到動畫器
(b)透過Add UIDynamicItems:設置對象。
例如:item1:設置gravity重力和collider碰撞
Item2:設置gravity重力
則item1不會和item2碰撞,會直接穿過item2,需要2個物件都設置相同的效果才會有作用。

(c)UIDynamicItem Protocol-動畫協定,動畫協定有3個屬性
(c.1)bounds:動畫範圍,此屬性只能讀(get)不能修改,因為動畫器無法改變物件的大小。
(c.2)center:定義對象的位置。
(c.3)transform:設定旋轉,為AffineTransform類型。
※目前UIView已包含此協定,故不需手動設置。
當要改變view的中心或是使view變形時需要透過updateItemUsingCurrentState(item:UIDynamicItem)
3.Behaviors(UIDynamicAnimator)
3.1UIGravityBehavior:重力行為,共有2個參數:
Angle:a設置角度
Magnitude:設置大小,比例1:1000,表示每平方秒1000像素
※因重力是一種加速度,在地球上是每坪方秒9.8米
3.2UIAttachmentBehavior:附屬行為的動畫效果
例如:增加一個錨點,配合重力產生擺動效果。
3.3UICollisionBehavior:碰撞行為,除了設定物件之間的碰撞之外也可設定物件與邊界的碰撞行為。
3.4兩種邊界設置的方法:
(a)UIBexierPath:貝賽爾曲線,以曲線作為邊界。
(b)translatesReferenceBoundsIntoBoundary:true表示動畫對象的所有外邊框為一個邊界
※設置邊界時需要設置識別符號,此符號遵循NSCopying Protocol,接受NSString 或 NSNumber。
※設置邊界時需設定代理UICollisionBehaviorDelegate,透過collisionBehavior取的物件之間或物件與邊界碰撞時的訊息。
參數:(1)item:UIDynamicItem(2) snaptoPoint:CGPoint那一個點
UIPushBehavior:將物件推向一個特定角度(擺動角度)
mode:UIPushBehaviorMode,共有2種model:(a).Continuous(b).Instantaneous
說明:Push行為可以是一次性的效果 、連續的效果,但重力只能是恆定速度。
Push加入動畫器時會影響動畫器中所有物件,但Push會有佔用資源問體,所以需要有取回資源機制。
UIDynamicItemBehavior:所有行為的父親,本身是UIDynamicBehavior的子類,用來取的物件動態行為的資訊,例如:移動的速度、角度、是否旋轉等。
透過addChildBehavior(UIDynamicBehavior )增加動態的行為,透過多個子行為達到複合行為效果。
※所有的行為一次只能在動畫器中(此屬性只能讀get)

func willMoveToAnimator:從沒有動畫移至有動畫時
重要屬性action: 是一個行為的屬性,當action是使用某個行為時會形成retain cycle,需要將參考的類型編碼為unowned來打破retain cycle
retain cycle補充說明:
範例:
在類別 A、B中的初始化方法中,各自產生了 A、B 的instance並將 A 、B 的instance賦值給 a.b 與b.a。這樣 a.b 和 b.a 將在初始化的時候形成一個引用循環。現在當有第三方的調用初始化了 A,然後即使立即將其釋放,A 和 B 兩個類實例的 deinit 方法也不會被調用,說明它們並沒有被釋放。
unowned :設置以後即使它原來引用的內容已經被釋放了,它仍然會保持對被已經釋放了的對象的一個 "無效的" 引用,它不能是 Optional 值,也不會被指向 nil。
weak :在引用的內容被釋放後,標記為 weak 的成員將會自動地變成 nil (因此被標記為 @weak 的變量一定需要是 Optional 值)。
關於兩者使用的選擇,Apple 給我們的建議是如果能夠確定在訪問時不會已被釋放的話,盡量使用 unowned,如果存在被釋放的可能,那就選擇用 weak。

UIDynamicAnimator同時擁有一個代理對象(UIDynamicAnimatorDelegate),負責提供:動畫是否已經停止、開始或暫停
func DynamicAnimatorWillResume(UIDynamicAnimator)
說明:當物件超過邊界時,他的物理行為還是持續,因次便可透過 DynamicAnimatorDidPause來停止物件的物理行為。
例如:當小球從頂層掉落超過底部時,仍會持續往下掉。
※永遠不要將一個view放在一個行為中,當一個 view不在參考view中的行為時,動畫器會使程式崩潰。
同樣不要對一個大小為0(0,0)的對象設置動畫,因為這是一個看不見得物件且這樣的設定不合理。
※Memory Cycle Avoidance
Push之後要移除Push行為
pushBehavior.DynamicAnimator!.removeBehavior(pushBehavior):在push的動作中參考到自己造成了 retain cycle 產生Memory action cycle
解決辦法:加入unowned pushBehavior表示push行為在封包中不會被強引用,所以不要捕獲他!
※強烈推薦在push 行為中加入此動作。
課程重點:
Physics based Dynamic Animation-物理動態動畫教學
Demo:打磚塊遊戲
1.Dynamic Animation
介紹:物理動畫與一般動畫不同在於,物理動畫指的是view上的物件,而一般動畫指的是整個view的動作。
2.使用物理動畫的步驟:
2.1建置一個UIDynamicAnimator
2.2加入UIDynamicAnimatorBehavios:增加動態行為,例如:加入重力或碰撞的效果
2.3加入UIDynamicItems:設置受影響的對象。
※將物理動畫效果設置在主View上,其SubView也會有相同效果。
程式範例:
(a)透過.addBehavior設置動畫行為到動畫器
(b)透過Add UIDynamicItems:設置對象。
例如:item1:設置gravity重力和collider碰撞
Item2:設置gravity重力
則item1不會和item2碰撞,會直接穿過item2,需要2個物件都設置相同的效果才會有作用。


(c)UIDynamicItem Protocol-動畫協定,動畫協定有3個屬性
(c.1)bounds:動畫範圍,此屬性只能讀(get)不能修改,因為動畫器無法改變物件的大小。
(c.2)center:定義對象的位置。
(c.3)transform:設定旋轉,為AffineTransform類型。
※目前UIView已包含此協定,故不需手動設置。
當要改變view的中心或是使view變形時需要透過updateItemUsingCurrentState(item:UIDynamicItem)
3.Behaviors(UIDynamicAnimator)
3.1UIGravityBehavior:重力行為,共有2個參數:
Angle:a設置角度
Magnitude:設置大小,比例1:1000,表示每平方秒1000像素
※因重力是一種加速度,在地球上是每坪方秒9.8米

3.2UIAttachmentBehavior:附屬行為的動畫效果
例如:增加一個錨點,配合重力產生擺動效果。
3.3UICollisionBehavior:碰撞行為,除了設定物件之間的碰撞之外也可設定物件與邊界的碰撞行為。

3.4兩種邊界設置的方法:
(a)UIBexierPath:貝賽爾曲線,以曲線作為邊界。
(b)translatesReferenceBoundsIntoBoundary:true表示動畫對象的所有外邊框為一個邊界
※設置邊界時需要設置識別符號,此符號遵循NSCopying Protocol,接受NSString 或 NSNumber。
※設置邊界時需設定代理UICollisionBehaviorDelegate,透過collisionBehavior取的物件之間或物件與邊界碰撞時的訊息。
Snap:指物件移動後會有一個擺盪動作。
UISnapBehavior:參數:(1)item:UIDynamicItem(2) snaptoPoint:CGPoint那一個點
UIPushBehavior:將物件推向一個特定角度(擺動角度)
mode:UIPushBehaviorMode,共有2種model:(a).Continuous(b).Instantaneous
說明:Push行為可以是一次性的效果 、連續的效果,但重力只能是恆定速度。
Push加入動畫器時會影響動畫器中所有物件,但Push會有佔用資源問體,所以需要有取回資源機制。
UIDynamicItemBehavior:所有行為的父親,本身是UIDynamicBehavior的子類,用來取的物件動態行為的資訊,例如:移動的速度、角度、是否旋轉等。
透過addChildBehavior(UIDynamicBehavior )增加動態的行為,透過多個子行為達到複合行為效果。
※所有的行為一次只能在動畫器中(此屬性只能讀get)

func willMoveToAnimator:從沒有動畫移至有動畫時
重要屬性action: 是一個行為的屬性,當action是使用某個行為時會形成retain cycle,需要將參考的類型編碼為unowned來打破retain cycle
retain cycle補充說明:
範例:
class A {
let b: B
init() {
b = B()
b.a = self
}
deinit {
println("A deinit")
}
}
class B {
var a: A? = nil
deinit {
println("B deinit")
}
}
範例說明:在類別 A、B中的初始化方法中,各自產生了 A、B 的instance並將 A 、B 的instance賦值給 a.b 與b.a。這樣 a.b 和 b.a 將在初始化的時候形成一個引用循環。現在當有第三方的調用初始化了 A,然後即使立即將其釋放,A 和 B 兩個類實例的 deinit 方法也不會被調用,說明它們並沒有被釋放。
unowned與weak的區別
unowned :設置以後即使它原來引用的內容已經被釋放了,它仍然會保持對被已經釋放了的對象的一個 "無效的" 引用,它不能是 Optional 值,也不會被指向 nil。
weak :在引用的內容被釋放後,標記為 weak 的成員將會自動地變成 nil (因此被標記為 @weak 的變量一定需要是 Optional 值)。
關於兩者使用的選擇,Apple 給我們的建議是如果能夠確定在訪問時不會已被釋放的話,盡量使用 unowned,如果存在被釋放的可能,那就選擇用 weak。

UIDynamicAnimator同時擁有一個代理對象(UIDynamicAnimatorDelegate),負責提供:動畫是否已經停止、開始或暫停
UIDynamicAnimatorDelegate
func DynamicAnimatorDidPause(UIDynamicAnimator)func DynamicAnimatorWillResume(UIDynamicAnimator)
說明:當物件超過邊界時,他的物理行為還是持續,因次便可透過 DynamicAnimatorDidPause來停止物件的物理行為。
例如:當小球從頂層掉落超過底部時,仍會持續往下掉。
※永遠不要將一個view放在一個行為中,當一個 view不在參考view中的行為時,動畫器會使程式崩潰。
同樣不要對一個大小為0(0,0)的對象設置動畫,因為這是一個看不見得物件且這樣的設定不合理。
※Memory Cycle Avoidance
Push之後要移除Push行為
pushBehavior.DynamicAnimator!.removeBehavior(pushBehavior):在push的動作中參考到自己造成了 retain cycle 產生Memory action cycle
解決辦法:加入unowned pushBehavior表示push行為在封包中不會被強引用,所以不要捕獲他!
※強烈推薦在push 行為中加入此動作。
留言
張貼留言
您好:
歡迎到訪我的Blog,這裡有我的生活經驗、美好的回憶和程式開發經驗分享~
目前努力學習Swift中,希望你會喜歡Swift!
如果可以也請你留言給我一個鼓勵喔!
謝謝