大部分人或許覺得動(dòng)畫用UIView 或是CoreAnimation的動(dòng)畫效果,那為何還需要UIKit 中的UIDynamic?
答:UIDynamic 為使用者提供更符合現(xiàn)實(shí)效果的互動(dòng)行為(比如:自由落體能量消耗的過程)
一歹茶、需求:請(qǐng)實(shí)現(xiàn)下圖所示的動(dòng)畫效果(物理碰撞)
二、上面引入過UIDynamic 可以實(shí)現(xiàn)碰撞的物理效果動(dòng)畫你弦,how to start ?
- 在工程中導(dǎo)入U(xiǎn)IKit惊豺,從Headers 找一些UIDynamic,發(fā)現(xiàn)了
UIDynamicAnimator.h
,UIDynamicBehavior
,UIDynamicItemBehavior
- 既然是要?jiǎng)赢嬓Ч?那就應(yīng)該是
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;
- 大概意思是使用這個(gè)初始化方法的時(shí)候鳖目,需要為你的試圖關(guān)聯(lián)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 行為相關(guān)類)描述什么行為呢彻磁?- UIAttachmentBehavior:附著行為
- UICollisionBehavior:碰撞行為
- UIGravityBehavior:重力行為
- UIDynamicItemBehavior:動(dòng)態(tài)元素行為
- UIPushBehavior:推行為
- UISnapBehavior:吸附行為
- 上述的各種行為可單獨(dú)使用,也可以組合使用更復(fù)雜的動(dòng)畫效果狸捅。
解決方案的思路就引導(dǎo)到這邊衷蜓,也就可以實(shí)現(xiàn)上述需求。Dynamic 行為相關(guān)類的屬性可自行研究尘喝。
三磁浇、解決方案。
- 上述需求的解決方案(我這邊用的是6sP的模擬器奧朽褪,因?yàn)樵谠O(shè)置floor的y坐標(biāo)是600)
- 既然是球落地效果置吓,必然有兩個(gè)模擬對(duì)象:floor无虚,basketBall
1.創(chuàng)建UIDynamicAnimator 對(duì)象
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
2.剛剛在API 看到了初始化UIDynamicAnimator需要關(guān)聯(lián)一個(gè)或者多個(gè)行為
NSArray *animatorObjects = @[self.imageV1];
// 剛剛在API 看到了初始化UIDynamicAnimator需要關(guān)聯(lián)一個(gè)或者多個(gè)行為
self.gravityBehav = [[UIGravityBehavior alloc] initWithItems:animatorObjects];
self.colision = [[UICollisionBehavior alloc] initWithItems:animatorObjects];
```
- 3.如果你想監(jiān)聽碰撞的狀態(tài),可以設(shè)置一下代理
```
self.colision.collisionDelegate = self;
```
- 4.設(shè)置碰撞邊界
```
[self.colision addBoundaryWithIdentifier:@"boundaryLine" fromPoint:CGPointMake(0, 600) toPoint:CGPointMake(SCREENWITH, 600)];
```
- 5.設(shè)置動(dòng)態(tài)行為參數(shù)
```
// 設(shè)置動(dòng)態(tài)行為參數(shù)
UIDynamicItemBehavior *itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:animatorObjects];
// 設(shè)置彈性
[itemBehavior setElasticity:0.5];
```
- 6.行為創(chuàng)建了衍锚,別忘了給animator添加上
```
[self.animator addBehavior:self.gravityBehav];
[self.animator addBehavior:self.colision];
[self.animator addBehavior:itemBehavior];
```
### 三友题、下面代碼只能說功能實(shí)現(xiàn)
- PS:以下代碼不符合代碼書寫規(guī)范
```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 {
// 創(chuàng)建碰撞需要的對(duì)象
[self jjCreateBall];
[self jjCreateFloor];
// 創(chuàng)建UIDynamicAnimator 對(duì)象
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
NSArray *animatorObjects = @[self.imageV1];
// 剛剛在API 看到了初始化UIDynamicAnimator需要關(guān)聯(lián)一個(gè)或者多個(gè)行為
self.gravityBehav = [[UIGravityBehavior alloc] initWithItems:animatorObjects];
self.colision = [[UICollisionBehavior alloc] initWithItems:animatorObjects];
// 這里設(shè)置代理是為了監(jiān)聽碰撞狀態(tài)的,可以去了解一下代理方法
self.colision.collisionDelegate = self;
// 設(shè)置碰撞邊界
[self.colision addBoundaryWithIdentifier:@"boundaryLine" fromPoint:CGPointMake(0, 600) toPoint:CGPointMake(SCREENWITH, 600)];
// 設(shè)置動(dòng)態(tài)行為參數(shù)
UIDynamicItemBehavior *itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:animatorObjects];
// 設(shè)置彈性
[itemBehavior setElasticity:0.5];
// 創(chuàng)建了行為需要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點(diǎn)擊下載
The last but not least:
1.如果想更好的玩轉(zhuǎn)UIDynamics請(qǐng)查閱fancypixel有關(guān)Playing With UIDynamics in iOS 9
PS:1.錄屏 Gif (for Mac)軟件:GIPHY CAPTURE
2.那個(gè)boundary(邊界)設(shè)置的適合下面的floor是一樣高的度宦,我選的圖片是有白色背景的方形(Rect),沒有把背景改成透明的告匠,會(huì)感覺到球的底面沒有和floor 重合的感覺戈抄。