ios-UIDynamic简介

本文详细介绍UIKit框架下的物理引擎UIDynamic,包括重力、碰撞、甩动等仿真行为的实现方式,并提供具体实例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

UIDynamic属于UIKit框架,可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象,比如说重力、弹性碰撞等现象。

UIDynamic的使用步骤

1、根据某个范围去创建动画者对象,就是在这个范围内去做动画

2、创建仿真行为,传入某个动力学元素,比如说需要做仿真行为的view

3、把仿真行为添加到动画者当中

Dynamic Animator 是动画者,负责做仿真动画的对象

Dynamic Animator Item 是动力学元素 做仿真行为的对象就是谁要去做仿真行为

UIDynamicBehavior 是仿真行为,就是做什么样的仿真的行为

UIDynamic提供了以下几种物理仿真行为
UIGravityBehavior:重力行为
UICollisionBehavior:碰撞行为
UISnapBehavior:甩行为
UIPushBehavior:推动行为
UIAttachmentBehavior:附着行为
UIDynamicItemBehavior:动力元素行为

在该控制器上面声明者如下属性

@property (nonatomic ,weak)UIView *blueview;
@property (nonatomic ,strong)UIDynamicAnimator * animator;

@property (nonatomic ,weak)UIView *greenview;

拿重力行为举个例子

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    //1、根据某个范围去创建动画者对象,就是在这个范围内去做动画
    self.animator=[[UIDynamicAnimator alloc]initWithReferenceView:self.view];
    //2、根据某一个动力学元素去创建行为
    //重力
    UIGravityBehavior * gravity=[[UIGravityBehavior alloc]initWithItems:@[self.blueview]];
    //用角度的方式改变重力的方向
    gravity.angle=M_PI_4;
    //用向量的形式去改变重力的方向
    gravity.gravityDirection=CGVectorMake(0, 1);
    //改变重力的量级其实就是改变重力的大小,越大重力越大
    //gravity.magnitude=50;
    3、把行为添加到动画者中
     [self.animator addBehavior:gravity];
} 

碰撞行为

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

{ 
UICollisionBehavior * collision=[[UICollisionBehavior alloc]initWithItems:@[self.blueview,self.greenview]]; 
//把引用的view也就是self.view的bounds作为边界
 collision.translatesReferenceBoundsIntoBoundary=YES; 
//碰撞的模式 collision.collisionMode=UICollisionBehaviorModeEverything;
// UICollisionBehaviorModeItems = 1 << 0,//仅仅是item之间发生碰撞
// UICollisionBehaviorModeBoundaries = 1 << 1,//仅仅是和边界发生碰撞
// UICollisionBehaviorModeEverything = NSUIntegerMax//和任何东西都发生碰撞
 //通过一条线创建一个边界 [collision addBoundaryWithIdentifier:@"key" fromPoint:CGPointMake(0, 200) toPoint:CGPointMake(250, 250)]; 
//可以通过UIBezierPath来设置边界 
UIBezierPath * path=[UIBezierPath bezierPathWithRect:self.greenview.frame]; 
[collision addBoundaryWithIdentifier:@"key1" forPath:path]; 
//这里可以实行实时的监听,只要view一动,就会去调用这个block方法 collision.action = ^{ };
 //设置代理 collision.collisionDelegate=self; 
//把行为添加到动画者当中
[self.animator addBehavior:collision];
}

//代理方法 
//item与边界之间的碰撞
- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(nullable id <NSCopying>)identifier atPoint:(CGPoint)p
{
    //id类型先强转一下为NSString类型
    NSString * str=(NSString *)identifier;
    //判断是否碰撞了画的那个边界
    if( [str isEqualToString:@"key"])
    {
        self.blueview.backgroundColor=[UIColor grayColor];
    }
    //就是撞到边界的情况
    else
    {
        self.blueview.backgroundColor=[UIColor redColor];
    }
}
甩行为

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    //获取手指对象
    UITouch * t=touches.anyObject;
    //获取当前位置
    CGPoint p=[t locationInView:t.view];
    //创建动画者对象
    self.animator=[[UIDynamicAnimator alloc]initWithReferenceView:self.view];
    //根据动力学元素创建行为
    UISnapBehavior * snap=[[UISnapBehavior alloc]initWithItem:self.blueview snapToPoint:p];
    //减速程序
    snap.damping=1;
    //添加到动画者对象中
    [self.animator addBehavior:snap];
}

附着行为分为弹性附着和刚性附着

刚性附着

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    //获取手指对象
    UITouch * t=touches.anyObject;
    //获取当前位置
    CGPoint p=[t locationInView:t.view];
    //创建动画者对象
    self.animator=[[UIDynamicAnimator alloc]initWithReferenceView:self.view];
    //创建行为把blueView的中心点和我们手指的位置连起来
    self.attach =[[UIAttachmentBehavior alloc]initWithItem:self.blueview attachedToAnchor:p];
    //固定刚性附着的杆的长度
    self.attach.length=100;
    //把行为添加到动画者中
    [self.animator addBehavior:self.attach];
}
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    //获取手指对象
    UITouch * t=touches.anyObject;
    //获取当前的位置
    CGPoint p=[t locationInView:t.view];
    //就是你附着的那个点让blueView跟着手指的位置移动
    self.attach.anchorPoint=p;
}
弹性附着和刚性附着就差两个属性

self.attach.damping=0.5;//减幅
self.attach.frequency=0.7;//频率

动力学元素的行为

 //动力学元素 自身属性
    UIDynamicItemBehavior * itemBehavior=[[UIDynamicItemBehavior alloc]initWithItems:@[self.blueview]];
    itemBehavior.elasticity=1;//弹力
    itemBehavior.density=1;//密度
    itemBehavior.friction=1;//摩擦力
    [self.animator addBehavior:itemBehavior];

推行为

#import "ViewController.h"

@interface ViewController ()
@property (nonatomic ,weak)UIView *redview;
@property (nonatomic ,strong)UIDynamicAnimator * animator;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    UIView * view=[[UIView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
    view.backgroundColor=[UIColor blueColor];
    self.redview=view;
    [self.view addSubview:view];
}


-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    UITouch * t=touches.anyObject;
    CGPoint p= [t locationInView:t.view];
    //创建动画者对象
    self.animator =[[UIDynamicAnimator alloc]initWithReferenceView:self.view];
    //创建行为
    UIPushBehavior * push=[[UIPushBehavior alloc]initWithItems:@[self.redview] mode:UIPushBehaviorModeInstantaneous];
    //推力的量级
    push.magnitude=1;
    //计算偏移量
    CGFloat offsetX=(p.x-self.redview.center.x);
    CGFloat offsetY=(p.y-self.redview.center.y);
    //设置push的角度
    //push.angle=M_PI;
    push.pushDirection=CGVectorMake(offsetX, offsetY);
    //添加行为到动画者对象中
    [self.animator addBehavior:push];
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值