三大概念
物理仿真元素
物理仿真行为
UIGravityBehavior:重力行为
UICollisionBehavior:碰撞行为
UISnapBehavior:捕捉行为
UIPushBehavior:推动行为
UIAttachmentBehavior:附着行为
UIDynamicItemBehavior:动力元素行为
物理仿真器
物理仿真器须知
UIDynamicAnimator的初始化
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;
代理对象(能监听物理仿真器的仿真过程,比如开始和结束)
创建一个物理仿真器(顺便设置仿真范围)
创建相应的物理仿真行为(顺便添加物理仿真元素)
将物理仿真行为添加到物理仿真器中 -> 开始仿真
让蓝色View执行仿真重力仿真行为,代码如下:
- (void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
// 创建一个物理仿真器,并指定参照系为控制器的View
UIDynamicAnimator *dynamicAnimator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
// 创建重力仿真行为并指定仿真元素为蓝色的view
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.blueView]];
// 把仿真行为添加到仿真器中
[dynamicAnimator addBehavior:gravity];
}
点击控制器的View,没有任何反应,这是因为还要没有执行动画物理仿真器就销毁,所以我们需要对物理仿真器有一个强引用 懒加载物理仿真器
定义物理仿真器属性
@property (nonatomic, strong) UIDynamicAnimator *dynamicAnimator;
懒加载物理仿真器器
- (UIDynamicAnimator *)dynamicAnimator
{
if (_dynamicAnimator == nil) {
// 创建一个物理仿真器,并指定参照系为控制器的View
_dynamicAnimator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
}
return _dynamicAnimator;
}
修改touchesBegan
方法
- (void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
// 创建重力仿真行为并指定仿真元素为蓝色的view
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.blueView]];
// 把仿真行为添加到仿真器中
[self.dynamicAnimator addBehavior:gravity];
}
如果想让blueView
到底部停止还需要添加一个碰撞行为
- (void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
// 创建重力仿真行为并指定仿真元素为blueView
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.blueView]];
// 创建一个碰撞的仿真行为并指定仿真元素为blueView
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.blueView]];
// 设置仿真边界为碰撞边界
collision.translatesReferenceBoundsIntoBoundary = YES;
// 添加碰撞行为到仿真器中
[self.dynamicAnimator addBehavior:collision];
// 把仿真行为添加到仿真器中
[self.dynamicAnimator addBehavior:gravity];
}
在storyboard上添加一个添加一个红色View,在蓝色的View下方,运行程序蓝色的View会从红色的View上方飘过,这是因为此时红色的View并没有添加到仿真器中,如果你希望蓝色的View撞到红色的View那么就需要把红色的View添加到碰撞的仿真行为中 1.红色View的拖线到控制器中,属性名称为redView 2.把红色View添加到碰撞仿真行为中
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.blueView,self.redView]];
添加碰撞边界
添加直线边界
- (void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
// 创建重力仿真行为并指定仿真元素为blueView
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.blueView]];
// 创建一个碰撞的仿真行为并指定仿真元素为blueView
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.blueView]];
// 设置仿真边界为碰撞边界
collision.translatesReferenceBoundsIntoBoundary = YES;
// 添加直线碰撞边界
[collision addBoundaryWithIdentifier:@"line" fromPoint:CGPointMake(0, self.view.frame.size.height * 0.5) toPoint:CGPointMake(self.view.frame.size.width, self.view.frame.size.height)];
// 添加碰撞行为到仿真器中
[self.dynamicAnimator addBehavior:collision];
// 把仿真行为添加到仿真器中
[self.dynamicAnimator addBehavior:gravity];
}
添加一个贝塞尔曲线碰撞边界,把添加直线碰撞边界的代码修改如下代码
// 添加贝塞尔曲线碰撞边界
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.width)];
[collision addBoundaryWithIdentifier:@"bezier" forPath:bezierPath];
重力行为的常见属性
//// 设置重力的角度,默认为M_PI_2(向下),0为右,M_PI向左
// gravity.angle = 0;
//// 设置重力的大小,默认是1
// gravity.magnitude = 2;
// 设置重力向量,(0,0) -> (1,1) 之间的连线,大小为:根号2
gravity.gravityDirection = CGVectorMake(1, 1);
捕获行为
// 相同类型仿真行为只能添加到仿真器一次,所以在添加仿真行为之前,移除之前添加仿真行为
[self.dynamicAnimator removeAllBehaviors];
// 获取描述用户点击的对象
UITouch *touch = [touches anyObject];
// 获取用户点击的位置
CGPoint loc = [touch locationInView:self.view];
// 创建一个捕获行为
UISnapBehavior *snap = [[UISnapBehavior alloc] initWithItem:self.blueView snapToPoint:loc];
// 设置减震效果,取值范围为 0.0 to 1.0. 0表示最小减震效果,也就是振幅最大
snap.damping = 0;
// 把捕获行为添加到仿真器中
[self.dynamicAnimator addBehavior:snap];
原文:http://www.cnblogs.com/YRFios/p/4963221.html