zoukankan      html  css  js  c++  java
  • iOS开发拓展篇—UIDynamic(重力行为+碰撞检测)

    iOS开发拓展篇—UIDynamic(重力行为+碰撞检测)

    一、重力行为

    说明:给定重力方向、加速度,让物体朝着重力方向掉落

    1.方法

    (1)UIGravityBehavior的初始化

      - (instancetype)initWithItems:(NSArray *)items;

        item参数 :里面存放着物理仿真元素

    (2)UIGravityBehavior常见方法

      - (void)addItem:(id <UIDynamicItem>)item;

        添加1个物理仿真元素

      - (void)removeItem:(id <UIDynamicItem>)item;

        移除1个物理仿真元素

    2.UIGravityBehavior常见属性

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

      添加到重力行为中的所有物理仿真元素

    @property (readwrite, nonatomic) CGVector gravityDirection;

      重力方向(是一个二维向量)

    @property (readwrite, nonatomic) CGFloat angle;

      重力方向(是一个角度,以x轴正方向为0°,顺时针正数,逆时针负数)

    @property (readwrite, nonatomic) CGFloat magnitude;

      量级(用来控制加速度,1.0代表加速度是1000 points /second²)

    二、碰撞行为

    1.简介

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

      可以通过添加边界(boundary),让物理碰撞局限在某个空间中

    2.UICollisionBehavior边界相关的方法

    - (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier forPath:(UIBezierPath*)bezierPath;

    - (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier fromPoint:(CGPoint)p1 toPoint:(CGPoint)p2;

    - (UIBezierPath*)boundaryWithIdentifier:(id <NSCopying>)identifier;

    - (void)removeBoundaryWithIdentifier:(id <NSCopying>)identifier;

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

    - (void)removeAllBoundaries;

    3.UICollisionBehavior常见用法

    @property (nonatomic, readwrite) BOOL translatesReferenceBoundsIntoBoundary;

      是否以参照视图的bounds为边界

    - (void)setTranslatesReferenceBoundsIntoBoundaryWithInsets:(UIEdgeInsets)insets;

      设置参照视图的bounds为边界,并且设置内边距

    @property (nonatomic, readwrite) UICollisionBehaviorMode collisionMode;

      碰撞模式(分为3种,元素碰撞、边界碰撞、全体碰撞)

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

      代理对象(可以监听元素的碰撞过程)

    三、代码示例

    在storyboard中拖拽几个控件,用于测试。

    测试代码:

    YYViewController.m文件

    //
    //  YYViewController.m
    //  12-重力行为和碰撞行为
    //
    //  Created by apple on 14-8-6.
    //  Copyright (c) 2014年 yangyong. All rights reserved.
    //
    
    #import "YYViewController.h"
    
    @interface YYViewController ()
    @property (weak, nonatomic) IBOutlet UIView *redView;
    
    @property (weak, nonatomic) IBOutlet UIProgressView *block1;
    @property (weak, nonatomic) IBOutlet UISegmentedControl *block2;
    
    @property(nonatomic,strong)UIDynamicAnimator *animator;
    @end
    
    @implementation YYViewController
    -(UIDynamicAnimator *)animator
    {
        if (_animator==nil) {
            //创建物理仿真器(ReferenceView:参照视图,设置仿真范围)
            self.animator=[[UIDynamicAnimator alloc]initWithReferenceView:self.view];
        }
        return _animator;
    }
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        //设置红色view的角度
        self.redView.transform=CGAffineTransformMakeRotation(M_PI_4);
    }
    
    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        //1.重力行为
    //    [self testGravity];
        //2.重力行为+碰撞检测
    //    [self testGravityAndCollsion];
        //3.测试重力的一些属性
        [self testGravityAndCollsion2];
        //用2根线作为边界
    //    [self testGravityAndCollision3];
        //4.用圆作为边界
    //    [self testGravityAndCollision4];
    }
    
    /**
     *  重力行为
     */
    -(void)testGravity
    {
        //1.创建仿真行为(进行怎样的仿真效果?)
        //重力行为
        UIGravityBehavior *gravity=[[UIGravityBehavior alloc]init];
        //2.添加物理仿真元素
        [gravity addItem:self.redView];
        //3.执行仿真,让物理仿真元素执行仿真行为
        [self.animator addBehavior:gravity];
    }
    /**
     *  重力行为+碰撞检测
     */
    -(void)testGravityAndCollsion
    {
        //1.重力行为
        UIGravityBehavior *gravity=[[UIGravityBehavior alloc]init];
        [gravity addItem:self.redView];
        
        //2碰撞检测行为
        UICollisionBehavior *collision=[[UICollisionBehavior alloc]init];
        [collision addItem:self.redView];
        [collision addItem:self.block1];
        [collision addItem:self.block2];
        
        //让参照视图的边框成为碰撞检测的边界
        collision.translatesReferenceBoundsIntoBoundary=YES;
        
        //3.执行仿真
        [self.animator addBehavior:gravity];
        [self.animator addBehavior:collision];
    }
    
    /**
     *  测试重力行为的属性
     */
    -(void)testGravityAndCollsion2
    {
        //1.重力行为
        UIGravityBehavior *gravity=[[UIGravityBehavior alloc]init];
        //(1)设置重力的方向(是一个角度)
    //    gravity.angle=(M_PI_2-M_PI_4);
        //(2)设置重力的加速度,重力的加速度越大,碰撞就越厉害
        gravity.magnitude=100;
        //(3)设置重力的方向(是一个二维向量)
        gravity.gravityDirection=CGVectorMake(0, 1);
        [gravity addItem:self.redView];
        
        //2碰撞检测行为
        UICollisionBehavior *collision=[[UICollisionBehavior alloc]init];
        [collision addItem:self.redView];
        [collision addItem:self.block1];
        [collision addItem:self.block2];
        
        //让参照视图的边框成为碰撞检测的边界
        collision.translatesReferenceBoundsIntoBoundary=YES;
        
        //3.执行仿真
        [self.animator addBehavior:gravity];
        [self.animator addBehavior:collision];
        
    }
    
    /**
     *  用圆作为边界
     */
    - (void)testGravityAndCollision4
    {
        // 1.重力行为
        UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init];
        [gravity addItem:self.redView];
        
        // 2.碰撞检测行为
        UICollisionBehavior *collision = [[UICollisionBehavior alloc] init];
        [collision addItem:self.redView];
        
        // 添加一个椭圆为碰撞边界
        UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 320, 320)];
        [collision addBoundaryWithIdentifier:@"circle" forPath:path];
        
        // 3.开始仿真
        [self.animator addBehavior:gravity];
        [self.animator addBehavior:collision];
    }
    
    /**
     *  用2根线作为边界
     */
    - (void)testGravityAndCollision3
    {
        // 1.重力行为
        UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init];
        [gravity addItem:self.redView];
        
        // 2.碰撞检测行为
        UICollisionBehavior *collision = [[UICollisionBehavior alloc] init];
        [collision addItem:self.redView];
        CGPoint startP = CGPointMake(0, 160);
        CGPoint endP = CGPointMake(320, 400);
        [collision addBoundaryWithIdentifier:@"line1" fromPoint:startP toPoint:endP];
        CGPoint startP1 = CGPointMake(320, 0);
        [collision addBoundaryWithIdentifier:@"line2" fromPoint:startP1 toPoint:endP];
    //    collision.translatesReferenceBoundsIntoBoundary = YES;
        
        // 3.开始仿真
        [self.animator addBehavior:gravity];
        [self.animator addBehavior:collision];
    }
    @end

    一些测试效果:

     

    代码补充说明:

    (1)加速度

    速度:point/s

    加速度:point/s²

    12 * 加速度 * t²

       gravity.magnitude = 1000; // 重力加速度越大,碰撞越厉害    

    (2)重力的方向

      坐标如下:

    重力方向(二维向量)

    说明:给定坐标平面内的一个点。然后用原点(0,0)来连接它,就构成了一个向量。

    注意:在IOS中以左上角为坐标原点,向右x增加,向下Y越大。

     

    1     //(3)设置重力的方向(是一个二维向量)
    2     gravity.gravityDirection=CGVectorMake(-1, 1);

    重力方向为左下角(西南)方向

    (3)碰撞检测行为

    UICollisionBehavior *collision = [[UICollisionBehavior alloc] init];
        [collision addItem:self.redView];
        CGPoint startP = CGPointMake(0, 160);
        CGPoint endP = CGPointMake(320, 400);
        [collision addBoundaryWithIdentifier:@"line1" fromPoint:startP toPoint:endP];
        CGPoint startP1 = CGPointMake(320, 0);
        [collision addBoundaryWithIdentifier:@"line2" fromPoint:startP1 toPoint:endP];

    注意:标识符不能写空。可以写字符串,因为需要标识符需要遵守NSCopying协议,而字符串满足要求。

    (4)贝赛尔曲线

    提示:这里的path是一个圆,设置宽高不一样,那么得出来的就是一个椭圆。

  • 相关阅读:
    Java实现 LeetCode 69 x的平方根
    Java实现 LeetCode 68 文本左右对齐
    Java实现 LeetCode 68 文本左右对齐
    Java实现 LeetCode 68 文本左右对齐
    Java实现 LeetCode 67 二进制求和
    Java实现 LeetCode 67 二进制求和
    Java实现 LeetCode 67 二进制求和
    Java实现 LeetCode 66 加一
    Java实现 LeetCode 66 加一
    CxSkinButton按钮皮肤类
  • 原文地址:https://www.cnblogs.com/yipingios/p/5566403.html
Copyright © 2011-2022 走看看