UIDynamic属于UIKit框架,可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象,比如说重力、弹性碰撞等现象。
UIDynamic的使用步骤
1、根据某个范围去创建动画者对象,就是在这个范围内去做动画
2、创建仿真行为,传入某个动力学元素,比如说需要做仿真行为的view
3、把仿真行为添加到动画者当中
Dynamic Animator 是动画者,负责做仿真动画的对象
Dynamic Animator Item 是动力学元素 做仿真行为的对象就是谁要去做仿真行为
UIDynamicBehavior 是仿真行为,就是做什么样的仿真的行为
UIDynamic提供了以下几种物理仿真行为
UIGravityBehavior:重力行为
UICollisionBehavior:碰撞行为
UISnapBehavior:甩行为
UIPushBehavior:推动行为
UIAttachmentBehavior:附着行为
UIDynamicItemBehavior:动力元素行为
在该控制器上面声明者如下属性
@property (nonatomic ,weak)UIView *blueview;
@property (nonatomic ,strong)UIDynamicAnimator * animator;
@property (nonatomic ,weak)UIView *greenview;
拿重力行为举个例子
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//1、根据某个范围去创建动画者对象,就是在这个范围内去做动画
self.animator=[[UIDynamicAnimator alloc]initWithReferenceView:self.view];
//2、根据某一个动力学元素去创建行为
//重力
UIGravityBehavior * gravity=[[UIGravityBehavior alloc]initWithItems:@[self.blueview]];
//用角度的方式改变重力的方向
gravity.angle=M_PI_4;
//用向量的形式去改变重力的方向
gravity.gravityDirection=CGVectorMake(0, 1);
//改变重力的量级其实就是改变重力的大小,越大重力越大
//gravity.magnitude=50;
3、把行为添加到动画者中
[self.animator addBehavior:gravity];
}
碰撞行为
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UICollisionBehavior * collision=[[UICollisionBehavior alloc]initWithItems:@[self.blueview,self.greenview]];
//把引用的view也就是self.view的bounds作为边界
collision.translatesReferenceBoundsIntoBoundary=YES;
//碰撞的模式 collision.collisionMode=UICollisionBehaviorModeEverything;
// UICollisionBehaviorModeItems = 1 << 0,//仅仅是item之间发生碰撞
// UICollisionBehaviorModeBoundaries = 1 << 1,//仅仅是和边界发生碰撞
// UICollisionBehaviorModeEverything = NSUIntegerMax//和任何东西都发生碰撞
//通过一条线创建一个边界 [collision addBoundaryWithIdentifier:@"key" fromPoint:CGPointMake(0, 200) toPoint:CGPointMake(250, 250)];
//可以通过UIBezierPath来设置边界
UIBezierPath * path=[UIBezierPath bezierPathWithRect:self.greenview.frame];
[collision addBoundaryWithIdentifier:@"key1" forPath:path];
//这里可以实行实时的监听,只要view一动,就会去调用这个block方法 collision.action = ^{ };
//设置代理 collision.collisionDelegate=self;
//把行为添加到动画者当中
[self.animator addBehavior:collision];
}
//代理方法
//item与边界之间的碰撞
- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(nullable id <NSCopying>)identifier atPoint:(CGPoint)p
{
//id类型先强转一下为NSString类型
NSString * str=(NSString *)identifier;
//判断是否碰撞了画的那个边界
if( [str isEqualToString:@"key"])
{
self.blueview.backgroundColor=[UIColor grayColor];
}
//就是撞到边界的情况
else
{
self.blueview.backgroundColor=[UIColor redColor];
}
}
甩行为
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//获取手指对象
UITouch * t=touches.anyObject;
//获取当前位置
CGPoint p=[t locationInView:t.view];
//创建动画者对象
self.animator=[[UIDynamicAnimator alloc]initWithReferenceView:self.view];
//根据动力学元素创建行为
UISnapBehavior * snap=[[UISnapBehavior alloc]initWithItem:self.blueview snapToPoint:p];
//减速程序
snap.damping=1;
//添加到动画者对象中
[self.animator addBehavior:snap];
}
附着行为分为弹性附着和刚性附着
刚性附着
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//获取手指对象
UITouch * t=touches.anyObject;
//获取当前位置
CGPoint p=[t locationInView:t.view];
//创建动画者对象
self.animator=[[UIDynamicAnimator alloc]initWithReferenceView:self.view];
//创建行为把blueView的中心点和我们手指的位置连起来
self.attach =[[UIAttachmentBehavior alloc]initWithItem:self.blueview attachedToAnchor:p];
//固定刚性附着的杆的长度
self.attach.length=100;
//把行为添加到动画者中
[self.animator addBehavior:self.attach];
}
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//获取手指对象
UITouch * t=touches.anyObject;
//获取当前的位置
CGPoint p=[t locationInView:t.view];
//就是你附着的那个点让blueView跟着手指的位置移动
self.attach.anchorPoint=p;
}
弹性附着和刚性附着就差两个属性
self.attach.damping=0.5;//减幅
self.attach.frequency=0.7;//频率
动力学元素的行为
//动力学元素 自身属性
UIDynamicItemBehavior * itemBehavior=[[UIDynamicItemBehavior alloc]initWithItems:@[self.blueview]];
itemBehavior.elasticity=1;//弹力
itemBehavior.density=1;//密度
itemBehavior.friction=1;//摩擦力
[self.animator addBehavior:itemBehavior];
推行为
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic ,weak)UIView *redview;
@property (nonatomic ,strong)UIDynamicAnimator * animator;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIView * view=[[UIView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
view.backgroundColor=[UIColor blueColor];
self.redview=view;
[self.view addSubview:view];
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UITouch * t=touches.anyObject;
CGPoint p= [t locationInView:t.view];
//创建动画者对象
self.animator =[[UIDynamicAnimator alloc]initWithReferenceView:self.view];
//创建行为
UIPushBehavior * push=[[UIPushBehavior alloc]initWithItems:@[self.redview] mode:UIPushBehaviorModeInstantaneous];
//推力的量级
push.magnitude=1;
//计算偏移量
CGFloat offsetX=(p.x-self.redview.center.x);
CGFloat offsetY=(p.y-self.redview.center.y);
//设置push的角度
//push.angle=M_PI;
push.pushDirection=CGVectorMake(offsetX, offsetY);
//添加行为到动画者对象中
[self.animator addBehavior:push];
}