iOS动力效果

/*

 UIDynamic 是从iOS7 开始引入的一种新计数,属于UIKit框架, 可以模拟显示生活中的物理现象 如碰撞 抖动 摆动等。

 动力效果就像咱们玩电吉他,电吉他也有效果器,可以添加各种电子效果

 动力效果也有一个效果器  叫做动力效果器 里面可以添加动力效果

 

 电吉他切换效果 会把上一个效果移除,动力效果也一样

 电吉他可以叠加多个效果 动力效果也是一样

 

 使用UIDynamic 步骤:

 1、创建一个动力效果器(UIDynamicAnimator

 2、创建动力效果(Behavior)添加到对应的视图上

 3、将动力效果添加到动力效果器中

 

 必须遵守了UIDynamicItem这个协议才可以使用动力效果

 UIView默认已经遵守了UIDynamicItem协议

 

 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轴正方向为,顺时针正数,逆时针负数)

 @property (readwrite, nonatomic) CGFloat magnitude;量级(用来控制加速度,1.0代表加速度是1000 points /second²)重力加速度越大 碰撞越厉害

 

 可以让物体之间实现碰撞效果

 也可以通过添加边界(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 物体就完全不会转动,而无论施加多大的转动力

 

 --------------------------------

 UIPushBehavior :推动效果

 

 typedef NS_ENUM(NSInteger, UIPushBehaviorMode) {

 UIPushBehaviorModeContinuous, 持续的力

 UIPushBehaviorModeInstantaneous 瞬间的力

 } NS_ENUM_AVAILABLE_IOS(7_0);

 @property (nonatomic, readonly) UIPushBehaviorMode mode; 推动效果的样式

 @property (nonatomic, readwrite) BOOL active; 是否激活

 @property (readwrite, nonatomic) CGFloat angle; 推动角度

 // A continuous force vector with a magnitude of 1.0, applied to a 100 point x 100 point view whose density value is 1.0, results in view acceleration of 100 points per s^2

 @property (readwrite, nonatomic) CGFloat magnitude; 推动力量

 @property (readwrite, nonatomic) CGVector pushDirection; 推动的方向

 

 

 ------------------------------

 UISnapBehavior:迅速移动效果

 // The point argument is expressed in the reference coordinate system

 - (instancetype)initWithItem:(id <UIDynamicItem>)item snapToPoint:(CGPoint)point;

 迅速移动效果 只能一次 添加到一个元素上  snapToPoint 让他移动到哪一个点

 

 @property (nonatomic, assign) CGFloat damping; // damping value from 0.0 to 1.0. 0.0 is the least oscillation. damping 的范围是(0.0-1.0

 

 ------------------------------

 UIAttachmentBehavior:附着效果

 

 吸附着一个视图 或者一个点  (也可以多个连接)

 

 附着效果 一个视图与一个锚点或者另一个视图相连接的情况

 附着行为描述的是两点之间的连接情况,可以模拟刚性或者弹性连接

 在多个物体间设定多个UIAttachmentBehavior,可以模拟多物体连接

 

 typedef NS_ENUM(NSInteger, UIAttachmentBehaviorType) {

 UIAttachmentBehaviorTypeItems, 吸附一个元素

 UIAttachmentBehaviorTypeAnchor 吸附一个点

 } NS_ENUM_AVAILABLE_IOS(7_0);

 设置吸附效果的样式

 @property (readonly, nonatomic) UIAttachmentBehaviorType attachedBehaviorType;

 

 @property (readwrite, nonatomic) CGPoint anchorPoint;锚点

 

 @property (readwrite, nonatomic) CGFloat length;距离 与锚点的距离

 @property (readwrite, nonatomic) CGFloat damping; // 1: critical damping  跳跃度

 @property (readwrite, nonatomic) CGFloat frequency; // in Hertz   幅度

 */


- (void)viewDidLoad {

    [super viewDidLoad];

    

//初始化动力效果器

    dynamicAnimator = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];

//    self.view 产生动力效果的有效区域

    

    dynamicAnimator.delegate = self;

    

    

    view1 = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];

    view1.center = self.view.center;

    view1.backgroundColor = [UIColor redColor];

    [self.view addSubview:view1];

    

    view2 = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 150)];

    view2.center = CGPointMake(self.view.center.x+100, self.view.center.y+100);

//    view2.layer.cornerRadius = 50;

    view2.backgroundColor = [UIColor yellowColor];

    [self.view addSubview:view2];

    

    view3 = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];

    view3.center = CGPointMake(self.view.center.x-50, self.view.center.y+150);

    view3.backgroundColor = [UIColor greenColor];

    view3.layer.cornerRadius = 50;

    [self.view addSubview:view3];

    

}


#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);

     view3.center = CGPointMake(self.view.center.x-50, self.view.center.y+150);

    

}


- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

{

#pragma mark-------- 重力效果

//    把之前添加过的效果移除

    [dynamicAnimator removeAllBehaviors];

    

//    初始化重力效果

//    initWithItems:@[view] view 上添加重力效果

    UIGravityBehavior *gravity = [[UIGravityBehavior alloc]initWithItems:@[view1]];

//    设置 加速度 数值越大 碰撞效果越大

    gravity.magnitude = 500;

  /*

   struct CGVector {

   CGFloat dx; 负数向左 正数向右

   CGFloat dy; 负数向上 正数向下

   };

   */

    

//    设置重力效果的方向

    gravity.gravityDirection = CGVectorMake(0, 1);

    

//    添加到效果器

    [dynamicAnimator addBehavior:gravity];

    

#pragma mark------碰撞效果------

    /*

//    view添加碰撞效果

    UICollisionBehavior *collision = [[UICollisionBehavior alloc]initWithItems:@[view1]];

//把动力效果器的范围 当做边界

//    collision.translatesReferenceBoundsIntoBoundary = YES;

    collision.collisionDelegate = self;

//  通关过两个点 画了一条直线当做边界

    

    [collision addBoundaryWithIdentifier:@"line1" fromPoint:CGPointMake(0, 300) toPoint:CGPointMake(400, 600)];

    [collision addBoundaryWithIdentifier:@"line2" fromPoint:CGPointMake(300, 0) toPoint:CGPointMake(300, 600)];

    

 

//    通过贝塞尔曲线画一个圆形

    UIBezierPath *linePath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 100, 300)];

    [collision addBoundaryWithIdentifier:@"xuanxing" forPath:linePath];

    [dynamicAnimator addBehavior:collision];

    

    */

    

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

    

    UICollisionBehavior *collision = [[UICollisionBehavior alloc]initWithItems:@[view1,view2,view3]];

    collision.translatesReferenceBoundsIntoBoundary = YES;

//    如果设置两个元素之间相互碰撞 设置了边界 也不起作用

    collision.collisionMode = UICollisionBehaviorModeEverything;

    collision.collisionDelegate = self;

    [dynamicAnimator addBehavior:collision];

    

#pragma mark------动力元素效果------

// 可以与其他的动力效果 配合使用

    UIDynamicItemBehavior *dynamicItem = [[UIDynamicItemBehavior alloc]initWithItems:@[view1,view2]];

//    设置元素的跳跃度 0-1

    dynamicItem.elasticity = 1;

    dynamicItem.friction = 1;

    [dynamicAnimator addBehavior:dynamicItem];

}


#pragma mark-----两个元素碰撞的代理方法

- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2 atPoint:(CGPoint)p{


 NSLog(@"碰撞的位置X%f Y:%f",p.x,p.y);

    

}

- (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(@"碰撞的位置X%f Y:%f",p.x,p.y);


}

- (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(id <NSCopying>)identifier{


    


}





#pragma mark-----动力效果器的代理方法

- (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator

{

    NSLog(@"启动");


}

- (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator{

    NSLog(@"暂停");

    

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值