zoukankan      html  css  js  c++  java
  • 效果器(两个动画之间的效果)

     

    /*

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

     UIDynamic 是从iOS 7开始引入的一种新技术,属于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就是他产生动力效果的有效范围

     

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

     动力效果器常用的属性

     @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;

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

     

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

     - (void)addBehavior:(UIDynamicBehavior *)behavior; 添加动力效果

     - (void)removeBehavior:(UIDynamicBehavior *)behavior; 移除动力效果

     - (void)removeAllBehaviors; 移除之前添加过的所有动力效果

     

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

    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²)重力加速度越大 碰撞越厉害

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

     

    2、UICollisionBehavior: 碰撞效果

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

     也可以通过添加边界(boundary)在边界实现碰撞效果

     

     常用属性:

     @property (nonatomic, readonly, copy) NSArray* items;

     @property (nonatomic, readwrite) UICollisionBehaviorMode collisionMode;

     @property (nonatomic, readwrite) BOOL translatesReferenceBoundsIntoBoundary;

     @property (nonatomic, readonly, copy) NSArray* boundaryIdentifiers;

     @property (nonatomic, assign, readwrite) id <UICollisionBehaviorDelegate> collisionDelegate;

     

     边界相关的方法

     - (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;

     

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

     3、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 物体就完全不会转动,而无论施加多大的转动力

     */

    #import "ViewController.h"

     

    @interface ViewController ()

    {

        UIDynamicAnimator *animator;

        UIView *view1;

        UIView *view2;

        UIView *view3;

        UIView *view4;

    }

    @end

     

    @implementation ViewController

     

    - (void)viewDidLoad {

        [super viewDidLoad];

     

        /**

          动力效果器(类)

         

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

         */

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

        animator.delegate = self;

     

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

        view1.center = CGPointMake(self.view.center.x-100, self.view.center.y-100);

        view1.backgroundColor = [UIColor greenColor];

        [self.view addSubview:view1];

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

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

        view2.backgroundColor = [UIColor redColor];

        [self.view addSubview:view2];

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

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

    //    view3.backgroundColor = [UIColor redColor];

    //    [self.view addSubview:view3];

    //    view4 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];

    //    view4.center = CGPointMake(self.view.center.x+150, self.view.center.y+150);

    //    view4.backgroundColor = [UIColor redColor];

    //    [self.view addSubview:view4];

    }

     

    #pragma mark - 手指触摸屏幕  触发动力效果  并执行

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

        UITouch *touch = [touches anyObject];

        CGPoint touchPoint = [touch locationInView:self.view];

        view1.center = touchPoint;

    //    view1.hidden = YES;

    }

     

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

    #pragma mark - 重力效果

    //     将之前 添加的动力效果 移除

        [animator removeAllBehaviors];

        

    //     在view1上添加重力效果

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

        

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

        gravity.magnitude = 2;

     

        

        /*

         struct CGVector {

         CGFloat dx;   负数向左  正数向右

         CGFloat dy;   负数向上  正数向下

         */

        //    设置重力方向

        gravity.gravityDirection = CGVectorMake(0, 1);

     

        

    //    添加到效果器  开始动力效果

        [animator addBehavior:gravity];

     

        

        

        

        

    #pragma mark - 碰撞效果

    //    给view1添加碰撞效果

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

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

    //    collision.translatesReferenceBoundsIntoBoundary = YES;

    //    collision.collisionDelegate = self;

    ////    通过两个点  画了一条线,当做碰撞效果的边界

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

    //    

    //    

    ////    通过贝塞尔曲线(UIBezierPath)画一个圈  当做碰撞效果的边界

    //    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 200, 200, 200)];

    //    [collision addBoundaryWithIdentifier:@"圆形" forPath:path];

    //    [animator addBehavior:collision];

        

    #pragma mark - 两个元素之间相互碰撞

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

        collision2.collisionDelegate = self;

        collision2.translatesReferenceBoundsIntoBoundary = YES;

    //    如果设置两个物体之间相互碰撞,设置了边界也就不管用了

        collision2.collisionMode = UICollisionBehaviorModeEverything;

        [animator addBehavior:collision2];

        

    #pragma mark- 动力元素效果

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

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

    //    设置元素的 弹性系数(0--1.0)

        item.elasticity = 1;

        [animator addBehavior:item];

        

    }

     

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

        

    }

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

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

        NSLog(@"启动");

    }

     

     

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

        NSLog(@"暂停");

    }

     

     

    - (void)didReceiveMemoryWarning {

        [super didReceiveMemoryWarning];

        // Dispose of any resources that can be recreated.

    }

     

    @end


  • 相关阅读:
    几种常用的曲线
    0188. Best Time to Buy and Sell Stock IV (H)
    0074. Search a 2D Matrix (M)
    0189. Rotate Array (E)
    0148. Sort List (M)
    0859. Buddy Strings (E)
    0316. Remove Duplicate Letters (M)
    0452. Minimum Number of Arrows to Burst Balloons (M)
    0449. Serialize and Deserialize BST (M)
    0704. Binary Search (E)
  • 原文地址:https://www.cnblogs.com/wukun16/p/4884173.html
Copyright © 2011-2022 走看看