UIDynamic

UIDynamic框架

 

簡介ide

什麼是UIDynamic動畫

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

能夠認爲是一種物理引擎,能模擬和仿真現實生活中的物理現象spa

重力、彈性碰撞等現象代理

 

物理引擎的價值對象

普遍用於遊戲開發,經典成功案例是「憤怒的小鳥繼承

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

提升了遊戲開發效率,產生更多優秀好玩的物理仿真遊戲ip

 

知名的2D物理引擎

Box2d

Chipmunk

使用步驟

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

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

 

建立相應的物理仿真行爲(順便添加物理仿真元素)

 

物理仿真行爲添加到物理仿真器中  開始仿真

三大概念

 

物理仿真元素(Dynamic Item

誰要進行物理仿真?

 

物理仿真行爲(Dynamic Behavior) 

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

 

物理仿真器(Dynamic Animator

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

物理仿真元素

注意

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

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

 

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

任何遵照了UIDynamicItem協議的對象

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

UICollectionViewLayoutAttributes類默認也遵照UIDynamicItem協議

 

物理仿真行爲

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

UIGravityBehavior:重力行爲

UICollisionBehavior:碰撞行爲

UISnapBehavior:捕捉行爲

UIPushBehavior:推進行爲

UIAttachmentBehavior:附着行爲

UIDynamicItemBehavior:動力元素行爲

 

物理仿真行爲須知

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

全部的UIDynamicBehavior均可以獨立進行

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

物理仿真器

物理仿真器須知

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

它是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;

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

重力行爲(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²

碰撞行爲(UICollisionBehavior

簡介

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

能夠經過添加邊界(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;

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

捕捉行爲(UISnapBehavior

簡介

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

 

UISnapBehavior的初始化

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

 

UISnapBehavior常見屬性

@property (nonatomic, assign) CGFloat damping;

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

 

UISnapBehavior使用注意

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

 

代碼示例

 

#import "ViewController.h"

 

@interface ViewController ()

 

@property (weak, nonatomic) IBOutlet UISegmentedControl *segment;

 

@property (strong, nonatomic) IBOutlet UIView *blueView;

/**

 *  物理仿真器

 */

@property (nonatomic,strong) UIDynamicAnimator *animator;

 

@end

 

@implementation ViewController

/**

 *  建立一次

 */

- (UIDynamicAnimator *)animator

{

    if (!_animator) {

        // 建立物理仿真器(ReferenceView, 參照視圖, 其實就是設置仿真範圍)

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

    }

    return _animator;

}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

{

//    [self testGravity];

//    [self testCollision];

    

//    吸附行爲(點哪裏吸哪裏)

    UITouch *touch = [touches anyObject];

    CGPoint point = [touch locationInView:self.view];

    

    //建立吸附行爲

    UISnapBehavior *snap = [[UISnapBehavior alloc] initWithItem:self.blueView snapToPoint:point];

    UISnapBehavior *sna2 = [[UISnapBehavior alloc] initWithItem:self.segment snapToPoint:point];

    //防抖係數(值越小,越抖)

    snap.damping = 0.3;

    

    //要想連續吸附,先刪除上一次的吸附行爲

    [self.animator removeAllBehaviors];

    //添加行爲

    [self.animator addBehavior:snap];

    [self.animator addBehavior:sna2];

 

    

}

/**

 *  重力行爲

 */

- (void)testGravity

{

    // 1.建立物理仿真行爲 - 重力行爲

    UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init];

    //誰要發生重力行爲

    [gravity addItem:self.blueView];

    //重力方向.100,100 11同樣,應爲它倆肯定一個角度

//    gravity.gravityDirection = CGVectorMake(100, 100);

    gravity.magnitude = 10;

    // 100 point/s²

    // 移動的距離 = 1/2 * magnitude * 時間²

    

    //2,添加物理仿真行爲到物理仿真器中,開始物理仿真

    [self.animator addBehavior:gravity];

}

/**

 *  碰撞行爲

 */

- (void)testCollision

{

    //1、建立 碰撞行爲

    UICollisionBehavior *collison = [[UICollisionBehavior alloc] init];

    //誰要放生碰撞行爲

    [collison addItem:self.blueView];

    [collison addItem:self.segment];

    

    //碰撞的邊界(以物理仿真器的邊界爲碰撞邊界)

//    collison.translatesReferenceBoundsIntoBoundary = YES;

    

    //自定義邊界

    CGFloat width = self.view.frame.size.width;

    //貝賽爾曲線

    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, width, width)];

    //傳一個路徑,碰撞邊界是一個路徑

    [collison addBoundaryWithIdentifier:@"circle" forPath:path];

    

    

    //2、建立重力行爲

    UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init];

    gravity.magnitude = 10;

    [gravity addItem:self.blueView];

    

    //3、添加行爲

    [self.animator addBehavior:gravity];

    [self.animator addBehavior:collison];

}

相關文章
相關標籤/搜索