简介:属于UIKit框架
- 什么是动力行为
* 模拟真实世界中力学相关的动画和交互系统
- 可以实现的效果
* 重力、碰撞、吸附、推动、捕捉效果,并且这些效果可以任意组合
- iOS9 之后增加了一个 UIDynamicItemGroup 可以统一给一组元素添加动力行为
- iOS9 之后 可以定义成以球形的方式去接触另一个边境或是元素
类名介绍
UIDynamicAnimator 动力效果播放者
包含的一些方法
- initWithReferenceView: 初始化动力效果播放者 并指定参考视图
- addBehavior: 添加动力行为
- removeBehavior:移除某个动力行为
- removeBehavior: 移除全部动力行为
- delegate 代理
UIGravityBehavior 重力效果行为
- 会影响到动力元素的属性(比如,frame)
- initWithItems:初始化重力效果行为 并指定作用对象
- addItem:添加重力效果作用对象
- removeItem:移除作用对象
- gravityDirection 重力的方向
- CGVector:表示矢量的结构体 值:0-1 受加速度的影响
- x:横向重力
- y:竖向重力
- Angle:更改重力效果的角度
- magnitude:加速度的级别 1.0代表加速度是1000 points /second²
- setAngle:magnitude:设置重力方向的角度 和速度
UICollisionBehavior 碰撞效果行为
(1)initWithItems:初始化方式
(2)collisionMode: 碰撞模式
《1》UICollisionBehaviorModeItems 元素碰撞
《2》UICollisionBehaviorModeBoundaries 边境碰撞
《3》UICollisionBehaviorModeEverything 所有都可以碰撞
(3)collisionDelegate 碰撞效果的代理
《1》元素碰撞的时候 调用以下方法
1.- (void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2 atPoint:(CGPoint)p
2.- (void)collisionBehavior:(UICollisionBehavior *)behavior endedContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2
《2》边境碰撞的时候 调用以下方法
1.- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(nullable id <NSCopying>)identifier atPoint:(CGPoint)p
2.- (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(nullable id <NSCopying>)identifier
(4)addBoundaryWithIdentifier:forPath: 添加路径 为边境
(5)- (nullable UIBezierPath *)boundaryWithIdentifier:(id <NSCopying>)identifier
(6)addBoundaryWithIdentifier:fromPoint:toPoint: 添加一条线为边境
(7)removeBoundaryWithIdentifier
(8)translatesReferenceBoundsIntoBoundary 是否 以参照视图作为边界
(9)setTranslatesReferenceBoundsIntoBoundaryWithInsets:设置参照视图的内间距
代码示例
//
// ViewController.m
// 动力行为
//
// Created by 安静srr on 16/4/14.
// Copyright © 2016年 安静SRR. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()<UIDynamicAnimatorDelegate,UICollisionBehaviorDelegate>
@property(nonatomic,strong) UIDynamicAnimator *animator;
@property(nonatomic,strong) UIImageView *ballItem;//动力效果元素
@property(nonatomic,strong) UIImageView *duangView;//碰到边界的时候出现的图片
@property (weak, nonatomic) IBOutlet UIImageView *bgImage;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
[self.bgImage 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",CGRectGetMaxY(self.ballItem.frame));
[self gravity];
[self collision];
}
//重力效果
- (void)gravity{
//移除之前的效果
[self.animator removeAllBehaviors];
UIGravityBehavior *gravity = [[UIGravityBehavior alloc]initWithItems:@[self.ballItem]];
/*
CGVector 表示方向的结构体
CGFloat dx : X轴的方向
CGFloat dy : Y轴的方向
gravityDirection 默认是(0.0,1.0)向下每秒下降1000个像素点 受其他因素的影响(加速度 弧度)
*/
gravity.gravityDirection = CGVectorMake(0.0, 1.0);
//会影响到重力的方向
// gravity.angle = 30*M_PI/180;
//magnitude 会影响到下降的速度
//gravity.magnitude = 100;
//把重力效果添加到动力效果的操纵者上
[self.animator addBehavior:gravity];
}
//MARK: -----检测碰撞的行为
- (void)collision{
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(400,680)];
collisionBehavior.collisionDelegate = self;
[self.animator 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{
self.duangView.center = CGPointMake(p.x-10, p.y-5);
[self.bgImage exchangeSubviewAtIndex:0 withSubviewAtIndex:1];
NSLog(@"开始接触到边境调用此方法");
}
- (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(nullable id <NSCopying>)identifier{
NSLog(@"结束接触到边境调用此方法");
}
//MARK: -------动力效果操纵者的代理方法
//动画开始调用
- (void)dynamicAnimatorWillResume:(UIDynamicAnimator *)animator{
}
//动画暂停调用
- (void)dynamicAnimatorDidPause:(UIDynamicAnimator *)animator{
}
//懒加载的方式创建动力效果播放者
-(UIDynamicAnimator *)animator{
if (_animator) {
return _animator;
}
_animator = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];
_animator.delegate = self;
return _animator;
}
//懒加载的方式创建作用对象
- (UIImageView *)ballItem{
if (_ballItem) {
return _ballItem;
}
_ballItem = [[UIImageView alloc]initWithFrame:CGRectMake(150, 50, 50, 50)];
_ballItem.image = [UIImage imageNamed:@"球"];
return _ballItem;
}
//当碰撞的时候会出现的视图
- (UIImageView *)duangView{
if (_duangView) {
return _duangView;
}
UIImage *image = [UIImage imageNamed:@"keng"];
_duangView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, image.size.width/2.5, image.size.height/2.5)];
_duangView.image = image;
[self.bgImage addSubview:_duangView];
[_duangView bringSubviewToFront:self.view];
return _duangView;
}
@end
注意:背景视图和作用对象是用storyboard创建的,如果不想用的话可以把这两个视图用代码写一下