UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架,可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象。
要想使用UIDynamic来实现物理仿真效果,大致的步骤如下:
1、创建一个物理仿真器(顺便设置仿真范围);
2、创建相应的物理仿真行为(顺便添加物理仿真元素)
3、将物理仿真行为添加到物理仿真器中 ---->开始仿真。
三大概念:
1、物理仿真元素(Dynamic Item):就是谁要进行物理仿真。
2、物理仿真行为(Dynamic Behavior): 就是执行怎样的物理仿真效果,怎样的动画效果。
3、物理仿真器(Dynamic Animator):就是让物理仿真元素执行具体的物理仿真行为。
》UIDynamic提供了以下几种物理仿真行为:
>UIGravityBehavior:重力行为
>UICollisionBehavior:碰撞行为
>UISnapBehavior:捕捉行为
>UIPushBehavior:推动行为
>UIAttachmentBehavior:附着行为
>UIDynamicItemBehavior:动力元素行为
》物理仿真行为须知
上述所有物理仿真行为都继承自UIDynamicBehavior
所有的UIDynamicBehavior都可以独立进行
组合使用多种行为时,可以实现一些比较复杂的效果
》物理仿真器须知
它可以让物理仿真元素执行物理仿真行为
它是UIDynamicAnimator类型的对象
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *blueView;
@property (weak, nonatomic) IBOutlet UISegmentedControl *segmentControl;
/** 物理仿真器 */
@property (nonatomic, strong) UIDynamicAnimator *animator;
@end
@implementation ViewController
- (UIDynamicAnimator *)animator {
if(!_animator) {
/** 创建物理仿真器(ReferenceView,参照视图,其实就是设置仿真范围好仿真坐标系) */
_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
}
return _animator;
}
- (void)viewDidLoad {
[super viewDidLoad];
// self.blueView.transform = CGAffineTransformMakeRotation(M_PI_4);
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
//碰撞行为
// [self testGravity];
// 碰撞行为
// [self testCollision];
// [self testCollision2];
//获得触摸点
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self.view];
//创建吸附/捕捉行为
UISnapBehavior *snap = [[UISnapBehavior alloc] initWithItem:self.blueView snapToPoint:point];
//防抖系数(值越小,越抖)
snap.damping = 1.0;
//添加行为
[self.animator removeAllBehaviors];
[self.animator addBehavior:snap];
}
/**
* 重力行为
*/
- (void)testGravity {
//1、创建重力仿真行为
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init];
//为物理仿真行为 添加仿真元素
[gravity addItem:self.blueView];
// [gravity addItem:self.segmentControl];
gravity.gravityDirection = CGVectorMake(6, 10);
//重力加速度
gravity.magnitude = 10;
//2、添加 物理仿真行为 到 物理仿真器中, 开始物理仿真
[self.animator addBehavior:gravity];
}
/**
* 碰撞行为
*/
- (void)testCollision {
//1、创建 碰撞行为
UICollisionBehavior *collision = [[UICollisionBehavior alloc] init];
//让参照视图的bounds变为碰撞检测的边框
collision.translatesReferenceBoundsIntoBoundary = YES;
//设置检测边框的内边距
// [collision setTranslatesReferenceBoundsIntoBoundaryWithInsets:UIEdgeInsetsMake(30, 30, 30, 30)];
//碰撞类型
collision.collisionMode = UICollisionBehaviorModeItems | UICollisionBehaviorModeBoundaries | UICollisionBehaviorModeEverything;
//添加仿真元素
[collision addItem:self.blueView];
[collision addItem:self.segmentControl];
//2、创建物理仿真行为 重力行为
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init];
gravity.magnitude = 10;
//添加仿真元素
[gravity addItem:self.blueView];
//3、添加行为
[self.animator addBehavior:collision];
[self.animator addBehavior:gravity];
}
- (void)testCollision2 {
//1、创建 碰撞行为
UICollisionBehavior *collision = [[UICollisionBehavior alloc] init];
//添加仿真元素
[collision addItem:self.blueView];
// [collision addItem:self.segmentControl];
//
// //添加边界
// CGFloat startX = 0;
// CGFloat startY = self.view.frame.size.height * 0.5;
// CGFloat endX = self.view.frame.size.width;
// CGFloat endY = self.view.frame.size.height;
// [collision addBoundaryWithIdentifier:@"line1" fromPoint:CGPointMake(startX, startY) toPoint:CGPointMake(endX, endY)];
// [collision addBoundaryWithIdentifier:@"line2" fromPoint:CGPointMake(endX, 0) toPoint:CGPointMake(endX, endY)];
CGFloat width = self.view.frame.size.width;
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, width, width)];
[collision addBoundaryWithIdentifier:@"circle" forPath:path];
//2、创建物理仿真行为
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init];
gravity.magnitude = 10;
//添加仿真元素
[gravity addItem:self.blueView];
//3、添加行为
[self.animator addBehavior:collision];
[self.animator addBehavior:gravity];
}