iOS UIKit Dynamics(物理碰撞,動畫)

大部分人或許覺得動畫用UIView 或是CoreAnimation的動畫效果,那為何還需要UIKit 中的UIDynamic?
答:UIDynamic 為使用者提供更符合現實效果的互動行為(比如:自由落體能量消耗的過程)

一、需求:請實現下圖所示的動畫效果(物理碰撞)

JJ's Animation.gif

二、上面引入過UIDynamic 可以實現碰撞的物理效果動畫,how to start ?

  • 在工程中導入UIKit,從Headers 找一些UIDynamic,發現了UIDynamicAnimator.h,UIDynamicBehavior,UIDynamicItemBehavior
  • 既然是要動畫效果 那就應該是UIDynamicAnimator.h
  • UIDynamicAnimator.h 頭文件去查看注釋
// When you initialize a dynamic animator with this method, you should only associates views with your behaviors.
// the behaviors (and their dynamic items) that you add to the animator employ the reference view’s coordinate system.
- (instancetype)initWithReferenceView:(UIView *)view NS_DESIGNATED_INITIALIZER;
  • 大概意思是使用這個初始化方法的時候,需要為你的試圖關聯behaviors
  • what's the behaviors ? jump into defination 然而還不是很懂,UIDynamicBehavior,那就查看API (注意文檔中的如下描述)。
  • This parent class, UIDynamicBehavior, is inherited by the primitive dynamic behavior classes UIAttachmentBehavior, UICollisionBehavior, UIGravityBehavior, UIDynamicItemBehavior, UIPushBehavior, and UISnapBehavior.
  • 文檔中提到UIDynamicBehavior的父類,那么UIDynamicBehavior父類(Dynamic 行為相關類)描述什么行為呢?
    • UIAttachmentBehavior:附著行為
    • UICollisionBehavior:碰撞行為
    • UIGravityBehavior:重力行為
    • UIDynamicItemBehavior:動態元素行為
    • UIPushBehavior:推行為
    • UISnapBehavior:吸附行為
  • 上述的各種行為可單獨使用,也可以組合使用更復雜的動畫效果。

解決方案的思路就引導到這邊,也就可以實現上述需求。Dynamic 行為相關類的屬性可自行研究。

三、解決方案。

  • 上述需求的解決方案(我這邊用的是6sP的模擬器奧,因為在設置floor的y坐標是600)
  • 既然是球落地效果,必然有兩個模擬對象:floor,basketBall
    • 1.創建UIDynamicAnimator 對象
      self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

    • 2.剛剛在API 看到了初始化UIDynamicAnimator需要關聯一個或者多個行為

NSArray *animatorObjects = @[self.imageV1];
 // 剛剛在API 看到了初始化UIDynamicAnimator需要關聯一個或者多個行為
 self.gravityBehav = [[UIGravityBehavior alloc] initWithItems:animatorObjects];
 self.colision = [[UICollisionBehavior alloc] initWithItems:animatorObjects];
     ```
   -  3.如果你想監聽碰撞的狀態,可以設置一下代理
   ```
 self.colision.collisionDelegate = self;
   ```
   - 4.設置碰撞邊界
   ```
[self.colision addBoundaryWithIdentifier:@"boundaryLine" fromPoint:CGPointMake(0, 600) toPoint:CGPointMake(SCREENWITH, 600)];
   ```
   - 5.設置動態行為參數
     ```
// 設置動態行為參數
 UIDynamicItemBehavior *itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:animatorObjects];
 // 設置彈性
 [itemBehavior setElasticity:0.5];
     ```
   - 6.行為創建了,別忘了給animator添加上
     ```
[self.animator addBehavior:self.gravityBehav];
 [self.animator addBehavior:self.colision];
 [self.animator addBehavior:itemBehavior];
     ```

### 三、下面代碼只能說功能實現
 - PS:以下代碼不符合代碼書寫規范
 
```objc
//
// ViewController.m
// DynamicAnimation
//
// Created by JeversonJee on 16/5/27.
// Copyright ? 2016年 JeversonJee. All rights reserved.
//

#import "ViewController.h"

#define SCREENWITH [UIScreen mainScreen].bounds.size.width
#define SCREENHEIGHT [UIScreen mainScreen].bounds.size.height

@interface ViewController ()<UICollisionBehaviorDelegate>

@property (nonatomic, strong) UIDynamicAnimator *animator;
@property (nonatomic, strong) UIGravityBehavior *gravityBehav;
@property (nonatomic, strong) UICollisionBehavior *colision;

@property (nonatomic, strong) UIImageView *imageV1;
@property (nonatomic, strong) UIImageView *imageV2;

@end

@implementation ViewController

- (void)viewDidLoad {
 [super viewDidLoad];
 // Do any additional setup after loading the view, typically from a nib.
 [self jjCollisionBehav];
}

- (void)jjCollisionBehav {
 // 創建碰撞需要的對象
 [self jjCreateBall];
 [self jjCreateFloor];
 // 創建UIDynamicAnimator 對象
 self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

 NSArray *animatorObjects = @[self.imageV1];
 // 剛剛在API 看到了初始化UIDynamicAnimator需要關聯一個或者多個行為
 self.gravityBehav = [[UIGravityBehavior alloc] initWithItems:animatorObjects];
 self.colision = [[UICollisionBehavior alloc] initWithItems:animatorObjects];
 // 這里設置代理是為了監聽碰撞狀態的,可以去了解一下代理方法
 self.colision.collisionDelegate = self;

 // 設置碰撞邊界
 [self.colision addBoundaryWithIdentifier:@"boundaryLine" fromPoint:CGPointMake(0, 600) toPoint:CGPointMake(SCREENWITH, 600)];
 // 設置動態行為參數
 UIDynamicItemBehavior *itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:animatorObjects];
 // 設置彈性
 [itemBehavior setElasticity:0.5];

 // 創建了行為需要animator添加
 [self.animator addBehavior:self.gravityBehav];
 [self.animator addBehavior:self.colision];
 [self.animator addBehavior:itemBehavior];

}

-(void)collisionBehavior:(UICollisionBehavior *)behavior endedContactForItem:(id<UIDynamicItem>)item withBoundaryIdentifier:(id<NSCopying>)identifier {

 NSLog(@"collisionBehavior=%@", item);
 NSString *identifierStr = [NSString stringWithFormat:@"%@", identifier];
 NSLog(@"s=%@", identifier);
 if ( [identifierStr isEqualToString:@"boundaryLine"] ) {
   [self.imageV2 setBackgroundColor:[UIColor grayColor]];
   [UIView animateWithDuration:2 animations:^(void){
     [self.imageV2 setBackgroundColor:[UIColor grayColor]];
   }];
 }

}

-(void)jjCreateBall {

 _imageV1 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"basketBall"]];
 _imageV1.frame = CGRectMake(100, 100, 60, 60);
 [self.view addSubview:_imageV1];
}

- (void)jjCreateFloor {

 _imageV2 = [[UIImageView alloc] init];

 [_imageV2 setBackgroundColor:[UIColor grayColor]];
 _imageV2.frame = CGRectMake(0, 600, SCREENWITH, SCREENHEIGHT - 400);
 [self.view addSubview:_imageV2];
}

-(void)didReceiveMemoryWarning {
 [super didReceiveMemoryWarning];
 // Dispose of any resources that can be recreated.
}

@end

四、UIDynamicDemo:GitHub/jeversonjee點擊下載

The last but not least:
1.如果想更好的玩轉UIDynamics請查閱fancypixel有關Playing With UIDynamics in iOS 9
PS:1.錄屏 Gif (for Mac)軟件:GIPHY CAPTURE
2.那個boundary(邊界)設置的適合下面的floor是一樣高的,我選的圖片是有白色背景的方形(Rect),沒有把背景改成透明的,會感覺到球的底面沒有和floor 重合的感覺。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 本文中所有代碼演示均有GitHub源碼,點擊下載 UIDynamic簡介 簡介:UIKit動力學最大的特點是將現實...
    si1ence閱讀 10,291評論 8 79
  • 目錄 ** UIView 動畫 ** ** Core Animation ** ** FaceBook POP動畫...
    方向_4d0d閱讀 1,656評論 0 3
  • UIKit Dynamics 是 iOS 7 中基于物理動畫引擎的一個新功能--它被特別設計使其能很好地與 col...
    評評分分閱讀 857評論 0 12
  • 前言: UIKit Dynamics是iOS7.0新增的一組類和方法,可以賦予UIView逼真的行為和特征,從而改...
    Y_小蔥閱讀 682評論 1 1
  • @柏雪有管理圖紙的案例,大連船柴、齊齊哈爾車輛廠、大連萬達都管理過圖紙,以齊齊哈爾用的最全面、最好
    阿連格格閱讀 38評論 0 0