- ios7 新增的UIKit Dynamics,讓UIView能夠模擬逼真的物理效果,通過使用UIDynamicItem協議及支持它的動態物體(dynamic item),可極大地改善用戶體驗。
- UIKit Dynamics提供了API使控件可以做到添加重力,碰撞,彈簧和吸附的效果。
- UIKit Dynamics是基本的UIKit物理引擎,但不像是傳統物理引擎那樣用于開發游戲。
- 要實現動態行為,可創建一個UIDynamicsAnimator(力學動畫生成器)對于每個力學動畫生成器,都可使各種屬性和行為進行定制, 如重力,碰撞,彈簧和吸附的效果。
UIDynamicsAnimator有6個可以定制的類:
UIDynamicAnimator 相當于一個manager,用于管理所有添加的力學行為
UIDynamicBehavior 所有力學行為的父類,是一個抽象類
UIGravityBehavior 重力
UICollisionBehavior 碰撞,彈力
UIAttachmentBehavior 吸附力
UIPushBehavior 推力
UISnapBehavior 甩行力
UIDynamicItemBehavior 自定義行為
- UIKit Dynamics 不太適合用于啟動了自動布局的UIView。在這些問題得到解決前,建議對要使用UIKit Dynamics實現動畫的視圖都禁用自動布局
UIDynamicAnimator
要創建新動畫并將其關聯到視圖,只需兩行代碼即可搞定。
1 - 新建一個項目,在viewController的ViewDidLoad里寫入以下代碼
- self.view設置為UIKit Dynamic行為的參考視圖
- 所有的動力行為都必須使用方法
addBehavior
將其加入力學動畫生成器 - 每個力學動畫生成器(UIDynamicAnimato)都是獨立的,多個力學動畫生成器可同時運行。
- 要讓力學動畫生成器持續運行,必須有指向它的有效引用。
- 相關的物體都出于靜止狀態后,力學動畫生成器將暫停,不在執行任何計算。
- 但對于未用的力學動畫生成器,推薦的做法是將其刪除。
重力行為
- 重力行為無疑是容易實現的,也是最實用的動態行為,ios7大量的使用了重力行為,用戶在鎖定屏幕上就可以看到這種效果,在ios7鎖定屏幕上,向上拖拽相機圖標在松開,將實用重力效果顯示主屏幕。在ios7之前,這種效果是使用定時器和動畫手工實現的。
示例:
1 - 創建一個test項目,在Main.storyboard中拖入控件UIImageView。(記得不要加自動布局)
2 - 由于我是想點擊屏幕后出現重力行為,所以,我在touchesBegan
方法中寫重力相關的代碼
2.1 - 我將重力效果添加進imageView1中,它是self.view的子視圖。
2.2 - 首先我創建了一個UIKit DynamicsAnimator,并將參考視圖指定為動態物體的父視圖(也就是self.view)
2.3 - 創建一個UIGravityBehavior對象,并使用一個數組來初始化他,該數組包含要對一個重力效果的視圖。
2.4 - 然后設置重力行為.
2.5 - 最后用addBehavior:將其加入UIDynamicAnimator。
效果
碰撞行為
重力效果
- 從上圖可以看到imageView只是隨著重力一直在下降,并沒有到達屏幕底部后停止,而是繼續下落
- 這是由于我們沒有指定的碰撞點,沒有東西組織物體往下落
- 這時我們就需要用到
碰撞
行為。
關于碰撞行為有3種模式
UICollisionBehaviorModeItems = 導致物體相互碰撞
UICollisionBehaviorModeBoundaries = 導致物體不相互碰撞,但與邊界碰撞
UICollisionBehaviorModeEverything = 導致物體急相互碰撞又與邊界碰撞
我們來看下3中行為的樣子:
1 - UICollisionBehaviorModeBoundaries行為(導致物體不相互碰撞,但與邊界碰撞)
qqq.gif
2 - UICollisionBehaviorModeEverything行為(導致物體急相互碰撞又與邊界碰撞)
qqq.gif
3 - UICollisionBehaviorModeItems行為 (導致物體相互碰撞 )
和第一種的樣子是一樣的,只是沒有了屏幕的邊界的攔截。
UICollisionBehaviorDelegate
在UICollisionBehavior對象中,還可以設置代理,指定的代理必須遵循協議
協議一共定義了4個回調方法:
Snip20161107_16.png
從圖上可以看出,有兩個是在碰撞開始的時候調用的,有2個是在碰撞結束后調用的,
在魅族回調方法中,一個指出了碰撞邊界,一個沒有指出,
所有方法都提供了一個引用,它指向導致方法被調用的對象,在碰撞開始時調用的方法中,都提供了一個CGPoint,它準確得指出了接觸點。