UIDynamic-动力效果

UIDynamic是从iOS 7开始引入的一种新技术 属于UIKit框架 可以模拟现实生活中的物理现象 如碰撞 抖动 摆动 等
玩 动力效果 如玩电吉他 电吉他的音效器 可以添加各种电子效果
动力效果 也有一个效果器 也叫动力效果器 里面可以添加动力效果

电吉他切换效果 会把上一个效果移除
动力效果 也是一样
电吉他可以叠加多个效果
动力效果 也是一样

使用UIDynamic的步骤
1、创建一个动力效果器(UIDynamicAnimator)
2、创建动力效果(Behavior)添加到对应的视图
3、将动力效果添加到动力效果器中

必须遵守了UIDynamicItme这个协议才可以使用动力效果
UIView默认已经遵守了UIDynamicItme协议

UIDynamic提供的动力效果
UIGravityBehavior:重力效果
UICollisionBehavior:碰撞效果
UIDynamicItemBehavior:动力元素效果
UIPushBehavior:推动效果
UISnapBehavior:迅速移动效果
UIAttachmentBehavior:附着效果

都继承自UIDynamicBehavior

动力效果器:UIDynamicAnimator
可以把UIDynamicAnimator看做动力效果的容器 它制定了动力效果的有效范围
在初始化的时候可以指定他的有效范围
- (instancetype)initWithReferenceView:(UIView*)view;
作用在哪一个view上 哪一个view就是他产生动力效果的有效范围

既然是容器 他还可以添加移除 动力效果

 - (void)addBehavior:(UIDynamicBehavior *)behavior; 添加动力效果
 - (void)removeBehavior:(UIDynamicBehavior *)behavior; 移除动力效果
 - (void)removeAllBehaviors; 移除之前添加过的所有动力效果

动力效果器常用的属性

@property (nonatomic, readonly) UIView* referenceView;作用的区域
 @property (nonatomic, readonly, copy) NSArray* behaviors;添加到效果器中的所有效果
 @property (nonatomic, readonly, getter = isRunning) BOOL running;是否正在进行
 @property (nonatomic, assign) id <UIDynamicAnimatorDelegate> delegate;可以检测开始暂停
 - (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator;
 - (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator;

Behavior 动力效果
1、重力效果UIGravityBehavior
设置重力的方向 加速度 让物体(视图) 朝重力的方向掉落

 @property (nonatomic, readonly, copy) NSArray *items;添加到重力效果中的所有效果作用对象
 @property (readwrite, nonatomic) CGVector gravityDirection;重力方向(是一个二维向量)以左上角为坐标原点 x 负数向左 正数向右  y 负数向上  正数向下  数字越大  重力效果越大
 @property (readwrite, nonatomic) CGFloat angle;重力方向(是一个角度,x轴正方向为0°,顺时针正数,逆时针负数)
 @property (readwrite, nonatomic) CGFloat magnitude;量级(用来控制加速度,1.0代表加速度是1000 points /second²)重力加速度越大 碰撞越厉害

UICollisionBehavior可以让物体之间实现碰撞效果
也可以通过添加边界(boundary)在边界实现碰撞效果
边界相关的方法

 - (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier forPath:(UIBezierPath*)bezierPath; 添加一个贝塞尔曲线路径的边界
 - (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier fromPoint:(CGPoint)p1 toPoint:(CGPoint)p2; 通过添加两个点连成的线 作为边界
 - (UIBezierPath*)boundaryWithIdentifier:(id <NSCopying>)identifier; 通过ID找到边界路径
 - (void)removeBoundaryWithIdentifier:(id <NSCopying>)identifier; 移除ID对应的边界
 @property (nonatomic, readonly, copy) NSArray* boundaryIdentifiers; 边界数组
 - (void)removeAllBoundaries;移除所有边界
 typedef NS_OPTIONS(NSUInteger, UICollisionBehaviorMode) {
 UICollisionBehaviorModeItems        = 1 << 0,元素碰撞
 UICollisionBehaviorModeBoundaries   = 1 << 1,边界碰撞
 UICollisionBehaviorModeEverything   = NSUIntegerMax 全体碰撞
 } NS_ENUM_AVAILABLE_IOS(7_0);

//两个元素相互碰撞

- (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:(id <NSCopying>)identifier atPoint:(CGPoint)p;
 - (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(id <NSCopying>)identifier;

UIDynamicItemBehavior 动力元素效果
可以设置 动力效果的默认值 是一个辅助的效果 设置运动学元素参与物理效果过程中的参数 如:弹性系数、摩擦系数、密度、阻力、角阻力以及是否允许旋转等
常用属性

@property (readwrite, nonatomic) CGFloat elasticity; // Usually between 0 (inelastic) and 1 (collide elastically) 属性设置碰撞弹性系数 范围(0.0-1.0)决定了碰撞的弹性程度,比如碰撞时物体的弹性
 @property (readwrite, nonatomic) CGFloat friction; // 0 being no friction between objects slide along each other设置摩擦系数 决定了沿接触面滑动时的摩擦力大小
 @property (readwrite, nonatomic) CGFloat density; // 1 by default 密度   跟size相关 计算物体的总质量 质量越大 物体加速或减速就越困难
 @property (readwrite, nonatomic) CGFloat resistance; // 0: no velocity damping (阻力):决定线性移动的阻力大小 与摩擦系数不同 摩擦系数只作用于滑动运动
 @property (readwrite, nonatomic) CGFloat angularResistance; // 0: no angular velocity damping 设置角度阻力系数。(0--CGFLOAT_MAX)决定旋转运动时的阻力大小
 @property (readwrite, nonatomic) BOOL allowsRotation; // force an item to never rotate 设置行为中的dynamic item是否可以旋转  设置这个属性为 NO 物体就完全不会转动,而无论施加多大的转动力

定义全局变量

UIDynamicAnimator *dynamicAnimator;
UIView *view1;
UIView *view2;

初始化动力效果器

dynamicAnimator  = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];
//    self.view产生动力效果的区域

挂上代理

 dynamicAnimator.delegate =self;
 //代理是:UIDynamicAnimatorDelegate

初始化两个视图:

view1 = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
    view1.center = self.view.center;
    view1.backgroundColor = [UIColor orangeColor];
    [self.view addSubview:view1];
    view2 = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 60, 60)];
    view2.center = CGPointMake(self.view.center.x +100, self.view.center.y +100);
    view2.backgroundColor = [UIColor colorWithRed:0.471 green:1.000 blue:0.832 alpha:1.000];
    [self.view addSubview:view2];
#pragma mark ---触摸屏幕 添加动力效果 并执行---------
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint touchPoint = [touch locationInView:self.view];
    view1.center = touchPoint;
    view2.center = CGPointMake(self.view.center.x +100, self.view.center.y +100);
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
//    把之前  添加过的动力 效果移除

    [dynamicAnimator removeAllBehaviors];
//    在view1上添加动力效果
    UIGravityBehavior *gravity = [[UIGravityBehavior alloc]initWithItems:@[view1]];
    gravity.magnitude = 100;
    /*
     设置动力效果的方向
     struct  CGVector{
     CGFloat dx;负数向左 正数向右
     CGFloat dy;负数向上 正数向下
     };

     */
//    设置动力效果的方向
    gravity.gravityDirection = CGVectorMake(0, 1);

//    添加到效果器 开始动力效果
    [dynamicAnimator addBehavior:gravity];


#pragma mark-----碰撞效果
//    UICollisionBehavior *collision = [[UICollisionBehavior alloc]initWithItems:@[view1]];
//    collision.collisionDelegate =self;
    把动力效果器的范围 当做边界
//    collision.translatesReferenceBoundsIntoBoundary = YES;

//    通过两个点画一条线 当做边界
//    [collision addBoundaryWithIdentifier:@"line1" fromPoint:CGPointMake(0, 300) toPoint:CGPointMake(400, 600)];
//    
//    [collision addBoundaryWithIdentifier:@"line2" fromPoint:CGPointMake(300, 0) toPoint:CGPointMake(300, 600)];

//    通过贝塞尔曲线 画一个圆形
//    UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 200, 300, 300)];
//    [collision addBoundaryWithIdentifier:@"圆形" forPath:path];

//    两个视图之间的相互碰撞

     UICollisionBehavior *collision = [[UICollisionBehavior alloc]initWithItems:@[view1,view2]];
    collision.translatesReferenceBoundsIntoBoundary = YES;

//    如果设置两个元素之间的 相互碰撞 边界设置则不管用
//    collision.collisionMode = UICollisionBehaviorModeItems;
    collision.collisionDelegate =self;

    [dynamicAnimator addBehavior:collision];

//
#pragma mark---------动力元素效果-----------
//    可以与其他的 动力效果 配合使用
    UIDynamicItemBehavior *itme = [[UIDynamicItemBehavior alloc]initWithItems:@[view1,view2]];
//    设置元素的跳跃度(0-1)
    itme.elasticity = 0.8;
    //把动力效果添加到容器里面
    [dynamicAnimator addBehavior:itme];

}

#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
{

//    view1.hidden =YES;
}
#pragma mark------ 碰撞效果代理-------
- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(id <NSCopying>)identifier atPoint:(CGPoint)p
{
    NSLog(@"%f,%f",p.x,p.y);
}
- (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(id <NSCopying>)identifier
{

}
#pragma mark ---动力效果器的代理方法---------
//启动
- (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator
{


}
//暂停
- (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator
{


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ldl_csdn_ios

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值