iOS開發之UIDynamic


1、概述
框架

什麼是UIDynamic?ide

UIDynamic是從iOS 7開始引入的一種新技術,隸屬於UIKit框架。動畫

能夠認爲是一種物理引擎,能模擬和仿真現實生活中的物理現象。好比:重力、彈性碰撞等現象。atom

物理引擎的價值:代理

(1)普遍用於遊戲開發,經典成功案例是「憤怒的小鳥」code

(2)讓開發人員能夠在遠離物理學公式的狀況下,實現炫酷的物理仿真效果對象

(3)提升了遊戲開發效率,產生更多優秀好玩的物理仿真遊戲繼承

知名的2D物理引擎:遊戲

Box2dip

Chipmunk

2、使用步驟

要想使用UIDynamic來實現物理仿真效果,大體的步驟以下:

第一步:建立一個物理仿真器(順便設置仿真範圍)。

第二步:建立相應的物理仿真行爲(順便添加物理仿真元素)。

第三步:將物理仿真行爲添加到物理仿真器中 à 開始仿真。

3、三大概念

物理仿真元素(Dynamic Item)

誰要進行物理仿真?

注意:

(1)不是任何對象都能作物理仿真元素

(2)不是任何對象都能進行物理仿真

這些對象才能作物理仿真元素:

(1)任何遵照了UIDynamicItem協議的對象

(2)UIView默認已經遵照了UIDynamicItem協議,所以任何UI控件都能作物理仿真

(3)UICollectionViewLayoutAttributes類默認也遵照UIDynamicItem協議

物理仿真行爲(Dynamic Behavior)

執行怎樣的物理仿真效果?怎樣的動畫效果?

UIDynamic提供瞭如下幾種物理仿真行爲:

UIGravityBehavior:重力行爲

UICollisionBehavior:碰撞行爲

UISnapBehavior:捕捉行爲

UIPushBehavior:推進行爲

UIAttachmentBehavior:附着行爲

UIDynamicItemBehavior:動力元素行爲

物理仿真行爲須知:

(1)上述全部物理仿真行爲都繼承自UIDynamicBehavior

(2)全部的UIDynamicBehavior均可以獨立進行

(3)組合使用多種行爲時,能夠實現一些比較複雜的效果

物理仿真器(Dynamic Animator)

讓物理仿真元素執行具體的物理仿真行爲

物理仿真器須知:

(1)它可讓物理仿真元素執行物理仿真行爲

(2)它是UIDynamicAnimator類型的對象

UIDynamicAnimator的初始化:

- (instancetype)initWithReferenceView:(UIView *)view;

view參數:是一個參照視圖,表示物理仿真的範圍

UIDynamicAnimator的常見方法:

- (void)addBehavior:(UIDynamicBehavior *)behavior;

添加1個物理仿真行爲

 

- (void)removeBehavior:(UIDynamicBehavior *)behavior;

移除1個物理仿真行爲

 

- (void)removeAllBehaviors;

移除以前添加過的全部物理仿真行爲

UIDynamicAnimator的常見屬性:

@property (nonatomic, readonly) UIView* referenceView;

參照視圖

 

@property (nonatomic, readonly, copy) NSArray* behaviors;

添加到物理仿真器中的全部物理仿真行爲

 

@property (nonatomic, readonly, getter = isRunning) BOOL running;

是否正在進行物理仿真

 

@property (nonatomic, assign) id <UIDynamicAnimatorDelegate> delegate;

代理對象(能監聽物理仿真器的仿真過程,好比開始和結束)

4、重力行爲(UIGravityAnimator

簡介:

給定重力方向、加速度,讓物體朝着重力方向掉落

UIGravityBehavior的初始化:

- (instancetype)initWithItems:(NSArray *)items;

item參數 :裏面存放着物理仿真元素

UIGravityBehavior常見方法:

- (void)addItem:(id <UIDynamicItem>)item;

添加1個物理仿真元素

 

- (void)removeItem:(id <UIDynamicItem>)item;

移除1個物理仿真元素

UIGravityBehavior常見屬性

@property (nonatomic, readonly, copy) NSArray* items;

添加到重力行爲中的全部物理仿真元素

 

@property (readwrite, nonatomic) CGVector gravityDirection;

重力方向(是一個二維向量)

 

@property (readwrite, nonatomic) CGFloat angle;

重力方向(是一個角度,以x軸正方向爲0°,順時針正數,逆時針負數)

 

@property (readwrite, nonatomic) CGFloat magnitude;

量級(用來控制加速度,1.0表明加速度是1000 points /second²)

例如,使一個UIImageView往下落效果

設置成員屬性:

@property (nonatomic, strong) UIDynamicAnimator *animator;

//第一步:建立一個物理仿真器(順便設置仿真範圍)。
self.animator =
[[UIDynamicAnimator alloc] initWithReferenceView:self.view];
//第二步:建立相應的物理仿真行爲(順便添加物理仿真元素)。
UIGravityBehavior *gravity =
[[UIGravityBehavior alloc] initWithItems:@[self.blueView]];
//第三步:將物理仿真行爲添加到物理仿真器中 à 開始仿真。
[self.animator addBehavior:gravity];
還能夠將碰撞行爲與上面重力行爲合成一個動畫,實現UIImageView落到屏幕最下邊時加一個彈跳效果:
//建立物理仿真行爲--->重力行爲(items: 物理仿真元素)
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.blueView]];
   
//碰撞檢測行爲
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.blueView]];//能夠添加多個,好比@[self.blueView,self.blueView2, self.blueView3]
// 讓參照視圖的bounds成爲碰撞檢測的邊框
collision.translatesReferenceBoundsIntoBoundary = YES;
   
//添加 物理仿真行爲 到 物理仿真器
[self.animator addBehavior:gravity];
[self.animator addBehavior:collision];

重點知識點:

若是讓你直接寫,你或許會這樣寫:

UIDynamicAnimator  *animator =

[[UIDynamicAnimator alloc] initWithReferenceView:self.view];

UIGravityBehavior *gravity =

[[UIGravityBehavior alloc] initWithItems:@[self.blueView]];

[animator addBehavior:gravity];

上面代碼不會實現預料效果,由於執行完上面代碼後animator會當即被銷燬,來不及實現動畫效果物理仿真器對象就被銷燬了。這就是上面爲何把仿真器設置爲成員屬性的緣由。這是個重要知識點,在其餘方面也會常常遇到。

5碰撞行爲(UICollisionBehavior

簡介:

(1)可讓物體之間實現碰撞效果

(2)能夠經過添加邊界(boundary),讓物理碰撞侷限在某個空間中

UICollisionBehavior邊界相關的方法:

- (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier forPath:(UIBezierPath*)bezierPath;

 

- (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier fromPoint:(CGPoint)p1 toPoint:(CGPoint)p2;

 

- (UIBezierPath*)boundaryWithIdentifier:(id <NSCopying>)identifier;

 

- (void)removeBoundaryWithIdentifier:(id <NSCopying>)identifier;

 

@property (nonatomic, readonly, copy) NSArray* boundaryIdentifiers;

 

- (void)removeAllBoundaries;

UICollisionBehavior常見用法:

@property (nonatomic, readwrite) BOOL translatesReferenceBoundsIntoBoundary;

是否以參照視圖的bounds爲邊界

 

- (void)setTranslatesReferenceBoundsIntoBoundaryWithInsets:

(UIEdgeInsets)insets;

設置參照視圖的bounds爲邊界,而且設置內邊距

 

@property (nonatomic, readwrite) UICollisionBehaviorMode collisionMode;

碰撞模式(分爲3種,元素碰撞、邊界碰撞、全體碰撞)

 

@property (nonatomic, assign, readwrite) id <UICollisionBehaviorDelegate> collisionDelegate;

代理對象(能夠監聽元素的碰撞過程)

6、捕捉行爲(UISnapBehavior

簡介:

可讓物體迅速衝到某個位置(捕捉位置),捕捉到位置以後會帶有必定的震動

UISnapBehavior的初始化:

- (instancetype)initWithItem:(id <UIDynamicItem>)item snapToPoint:

(CGPoint)point;

UISnapBehavior常見屬性:

@property (nonatomic, assign) CGFloat damping;

用於減幅、減震(取值範圍是0.0 ~ 1.0,值越大,震動幅度越小)

UISnapBehavior使用注意:

若是要進行連續的捕捉行爲,須要先把前面的捕捉行爲從物理仿真器中移除

相關文章
相關標籤/搜索