动力效果的实现首先由一个UIDynamicAnimator动画的绘制者 ,给他一个UIDynamicBehavior动力效果 、 把UIDynamicItem(UIView)动力元素添加到动力效果上
动力元素:只要遵守了UIDynamicItem这个协议的都可以看成动力行为的元素
UIDynamicAnimator动画的绘制者 需要一个作用的区域范围()
他们的关系结构图如下:
动力行为:
1.简介:属于UIKit
(1)什么是动力行为? -> 模拟真实世界中力学相关的动画和交互系统
(2)可以实现的效果: -> 重力、碰撞、吸附、推动、捕捉效果、并且可以组合
(3)iOS9 UIDynamicItemGroup可以统一给一组元素添加动力行为
(4)iOS9 可以定义成 以球形方式 去接触 另一个边境 或元素
2.类名介绍:
(1)UIDynamicAnimator:动力效果的动画播放者
属性介绍:
①initWithReferenceView:初始化动力效果播放者 并制定参考视图
②addBehavior:添加动力行为
③removeBehavior:移除某个动力行为
④removeAllBehaviors 移除所有动力行为
⑤delegate 代理
(2)UIDynamicBehavior:动力效果的动画行为 动力效果的动画行为会影响到动力元素的属性(frame)
动力行为分六大行为:
《1》UIGravityBehavior 重力效果行为
①initWithItems:初始化重力效果行为 并指定作用对象
②addItem:添加重力效果作用对象
③removeItem:移除作用对象
④gravityDirection重力的方向
CGVector:表示矢量的结构体 值:0-1
x:横向重力
y:竖向重力
受加速度、弧度的影响 每秒下降1000个像素点
⑤angle:更改重力效果的角度
⑥magnitude:加速度的级别 1.0代表加速度是1000 points /second²
⑦setAngle:magnitude:设置重力方向的角度 和速度
《2》UICollisionBehavior 碰撞行为
①initWithItems:初始化
②collisionMode:碰撞样式(模式)
UICollisionBehaviorModeItems 元素碰撞
UICollisionBehaviorModeBoundaries 边境碰撞
UICollisionBehaviorModeEverything 所有都可以碰撞
③collisionDelegate:代理
④元素碰撞的时候调用的代理方法
- (void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2 atPoint:(CGPoint)p;
- (void)collisionBehavior:(UICollisionBehavior *)behavior endedContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2;
⑤元素与边境之间碰撞的时候调用的代理方法
- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(nullable id <NSCopying>)identifier atPoint:(CGPoint)p;
- (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(nullable id <NSCopying>)identifier;
⑥addBoundaryWithIdentifier:forPath: 添加路径 为边境
⑦- (nullable UIBezierPath *)boundaryWithIdentifier:(id <NSCopying>)identifier
⑧addBoundaryWithIdentifier:fromPoint:toPoint: 添加一条线为边境
⑨removeBoundaryWithIdentifier
⑩translatesReferenceBoundsIntoBoundary 是否以参照视图作为边界
⑪setTranslatesReferenceBoundsIntoBoundaryWithInsets:设置参照视图的内间距
《3》UIPushBehavior 推动行为
《4》UISnapBehavior 迅速移动
《5》UIAttachmentBehavior 附和行为
《6》UIDynamicItemBehavior 元素行为
(3)UIDynamicItem动力元素
以上就是关于动力行为的介绍,具体操作如下:
首先在Main.sroryBoard里面创建一个UIImageView,设置属性全屏、允许与用户交互、image。同时把ImageView拖到ViewController.m文件
@interface里面
#import "ViewController.h" @interface ViewController ()<UIDynamicAnimatorDelegate,UICollisionBehaviorDelegate> //动力效果的元素 @property(nonatomic,strong)UIImageView *ballItem; @property (weak, nonatomic) IBOutlet UIImageView *bgView; @property(nonatomic,strong)UIDynamicAnimator *animatior; //碰撞到边境出现的图片 @property(nonatomic,strong)UIImageView *dungView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; [self.bgView addSubview:self.ballItem]; } - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ self.ballItem.center = [[touches anyObject] locationInView:self.view]; } - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ self.ballItem.center = [[touches anyObject] locationInView:self.view]; } //拖动完之后让球掉落 - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ NSLog(@"Y:%f",self.ballItem.frame.origin.y); [self gravityBehavior]; [self collisionBehavior]; } #pragma mark-------重力效果 - (void)gravityBehavior{ //移除之前的效果 [self.animatior removeAllBehaviors]; UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc]initWithItems:@[self.ballItem]]; gravityBehavior.gravityDirection = CGVectorMake(0.0, 1.0); //重力的方向 //gravityBehavior.angle = 30*M_PI/180; //加速度 会影响下降速度 gravityBehavior.magnitude = 1.5; //把重力效果添加到动力效果的操纵者上 [self.animatior addBehavior:gravityBehavior]; } #pragma mark-----检测碰撞的行为 - (void)collisionBehavior{ UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc]initWithItems:@[self.ballItem]]; //设置碰撞的样式(模式) collisionBehavior.collisionMode = UICollisionBehaviorModeEverything; //是否 以参照视图作为边界 //collisionBehavior.translatesReferenceBoundsIntoBoundary = YES; //画圆 //UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(20, 300, 300, 300) cornerRadius:150]; //[collisionBehavior addBoundaryWithIdentifier:@"round" forPath:path]; //画线 [collisionBehavior addBoundaryWithIdentifier:@"line" fromPoint:CGPointMake(0, 680) toPoint:CGPointMake(414, 680)]; collisionBehavior.collisionDelegate = self; [self.animatior addBehavior:collisionBehavior]; } #pragma mark--------碰撞行为的代理方法 //元素之间的碰撞 - (void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2 atPoint:(CGPoint)p{ } - (void)collisionBehavior:(UICollisionBehavior *)behavior endedContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2{ } //元素与边境之间的碰撞 - (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(nullable id <NSCopying>)identifier atPoint:(CGPoint)p{ NSLog(@"开始接触边境"); self.dungView.center = CGPointMake(p.x-20, p.y-20); //[self.dungView addSubview:self.ballItem]; [self.bgView exchangeSubviewAtIndex:1 withSubviewAtIndex:0]; } - (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(nullable id <NSCopying>)identifier{ NSLog(@"结束接触边境"); [behavior removeBoundaryWithIdentifier:@"line"]; [self collisionBehavior]; } #pragma mark--------UIDynamicAnimatorDelegate(动力效果操纵者)的两个代理方法 - (void)dynamicAnimatorWillResume:(UIDynamicAnimator *)animator{ NSLog(@"开始"); } - (void)dynamicAnimatorDidPause:(UIDynamicAnimator *)animator{ NSLog(@"暂停"); } - (UIImageView *)ballItem{ if (_ballItem) { return _ballItem; } _ballItem = [[UIImageView alloc]initWithFrame:CGRectMake(100, 50, 50, 50)]; _ballItem.image = [UIImage imageNamed:@"球"]; return _ballItem; } - (UIDynamicAnimator *)animatior{ if (_animatior) { return _animatior; } _animatior = [[UIDynamicAnimator alloc]initWithReferenceView:self.view]; _animatior.delegate = self; return _animatior; } - (UIImageView *)dungView{ if (_dungView) { return _dungView; } UIImage *image = [UIImage imageNamed:@"keng"]; _dungView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 680, image.size.width/2.5, image.size.height/2.5)]; _dungView.image = image; [self.bgView addSubview:_dungView]; return _dungView; } @end
运行的效果就是当你拖动完之后小球掉落会出现一个坑。、
效果如下: