文档章节

UIDynamic

工匠心
 工匠心
发布于 2016/05/22 08:38
字数 2393
阅读 18
收藏 0

一、UIDynamic介绍

 

1. 什么是UIDynamic

UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架 可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象 :重力、弹性碰撞等现象

注意:UIKit动力学的引入,并不是为了替代CA或者UIView动画,在绝大多数情况下CA UIView动画仍然是最优方案,只有在需要引入逼真的交互设计的时候,才需要使用 UIKit动力学它是作为现有交互设计和实现的一种补充

演示

 

2. 物理引擎的价值 广泛用于游戏开发,经典成功案例是愤怒的小鸟让开发人员可以在远离物理学公式的情况下,实现炫酷的物理仿真效果 提高了游戏开发效率,产生更多优秀好玩的物理仿真游戏

 

3. 知名的2D物理引擎 Box2d Chipmunk

 

4. 相关概念

 

a. 谁要进行物理仿真?(要谁做)

物理仿真元素(Dynamic Item)

是任何遵守了UIDynamicItem协议的对象

 

b. 执行怎样的物理仿真效果?怎样的动画效果?(做什么动画)

物理仿真行为(Dynamic Behavior) 仿真行为,是动力学行为的父类,基本的动力学行为类 UIGravityBehaviorUICollisionBehaviorUIAttachmentBehaviorUISnapBehaviorUIPushBehavior以及UIDynamicItemBehavior均继承自该父类,可以组合使用

 

c. 让物理仿真元素执行具体的物理仿真行为(开始做) 物理仿真器(Dynamic Animator)

为动力学元素提供物理学相关的能力及动画,同时为这些元素提供相关的上下文,是动力学元素与底层iOS物理引擎之间的中介,Behavior对象添加到 Animator即可实现动力仿真

 

d. 注意不是任何对象都可以做物理仿真效果 物理仿真元素要素:

任何遵守了UIDynamicItem协议的对象 UIView默认已经遵守了UIDynamicItem协议,因此任何UI控件都能做物理仿真 UICollectionViewLayoutAttributes类默认也遵守UIDynamicItem协议

 

 

 

二、相关类和使用步骤

1. 物理仿真元素()

UIDynamicItem

 

2. 物理仿真行为(做什么)

UIGravityBehavior:重力行为 UICollisionBehavior:碰撞行为 UISnapBehavior:捕捉行为 UIPushBehavior:推动行为 UIAttachmentBehavior:附着行为 UIDynamicItemBehavior:动力元素行为

 

3. 物理仿真器(开始做) UIDynamicAnimator

 

4. 使用步骤

a. 创建一个UIDynamicAnimator对象

b. 创建行为对象(UIDynamicBehavior)

c. 将要执行动画的对象添加到UIDynamicBehavior

一般会将 UIView 添加到行为对象中 UIView 遵守了UIDynamicItem协议

 

 

 

 

三、物理仿真行为 UIDynamic的物理仿真行为只能针对矩形操作。不支持其它形状

 

 

 

01-重力行为(Gravity)

1. 重力行为用于给动力学元素指定一个重力向量

2. 代码示例

//1 创建物理仿真器

UIDynamicAnimator *animator = [[UIDynamicAnimator alloc]

                               initWithReferenceView:self.redView];

self.animator = animator;

//2 创建重力行为(物理行为)

UIGravityBehavior *behavior = [[UIGravityBehavior alloc]

                               initWithItems:@[self.redView]];

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

 

behavior.magnitude = 0.2;

//方向

//

behavior.gravityDirection = CGVectorMake(1, 1);

behavior.angle = 0;

//3 把物理行为添加到物理仿真器中 开始动画

[animator addBehavior:behavior];

 

 

 

02-碰撞行为(Collision)

1. 相关属性

translatesReferenceBoundsIntoBoundary

translatesReferenceBoundsIntoBoundary设置为YES而不是明确的添加边界的坐标。这样会使这

个边界使用 UIDynamicAnimator 提供的参考系的边界。

collisionMode

UICollisionBehaviorModeItems 碰到元素碰撞,边界不碰撞

UICollisionBehaviorModeBoundaries 碰到边界碰撞,元素不碰撞

UICollisionBehaviorModeEverything 默认,碰到边界或元素会发生碰撞

2. 代码示例

//1 创建物理仿真器,动画的范围

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

//2 创建物理仿真行为

//2.1 重力行为

UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.redView]];

//2.2 碰撞行为

UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.redView]];

//2.3 碰撞的边界,translatesReferenceBoundsIntoBoundary设置为YES而不是明确的添加边界的坐

//标。这样会使这个边界使用 UIDynamicAnimator 提供的参考系的边界。

collision.translatesReferenceBoundsIntoBoundary = YES;

//3 把物理仿真行为添加到物理仿真器中

[self.animator addBehavior:gravity];

[self.animator addBehavior:collision];

 

 

碰撞行为-其它

1. 两种自定义边界的方式,设置直线

a. 添加边界,设置两个点

[collision addBoundaryWithIdentifier:@"b1" fromPoint:CGPointMake(0, 200) toPoint:CGPointMake(180, 250)];

 

b. 使用路径的方式

UIBezierPath *path = [UIBezierPath bezierPath];

[path moveToPoint:CGPointMake(0, 200)];

[path addLineToPoint:CGPointMake(180, 250)];

[collision addBoundaryWithIdentifier:@"b1" forPath:path];

 

2. 自定义边界,设置矩形的边界

UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 200, 180, 20)];

 

[collision addBoundaryWithIdentifier:@"b2" forPath:path];

 

3. 碰撞过程中监听frame的变化 [collision setAction:^{

    NSLog(@"%@",NSStringFromCGRect(self.redView.frame)); }];

 

4. 碰撞行为的弹力系数(0-1之间)

UIDynamicItemBehavior *item = [[UIDynamicItemBehavior alloc] initWithItems: @[self.redView]];

item.elasticity = 1;

 

添加到物理仿真器中

[self.animator addBehavior:item];

5. 设置碰撞行为的代理,碰撞到边界以后改变物体的状态

- (void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id)item withBoundaryIdentifier:(id)identifier atPoint:(CGPoint)p {

    //开始的碰撞物体

    UIView *view = (UIView *)item;

    //边界的id

    NSString *strId = (NSString *)identifier;

    //当碰撞到黄色边界以后改变当前物体的颜色

    if ([strId isEqualToString:@"b2"]) {

    [UIView animateWithDuration:0.3 animations:^{

        view.backgroundColor = [UIColor blackColor];

    } completion:^(BOOL finished) {

        view.backgroundColor = [UIColor redColor]; }];

} }

 

 

 

四、捕捉(也叫吸附)行为(Snap)

1. 代码示例

//1 物理仿真器

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

//2 创建捕捉行为

UISnapBehavior *snap = [[UISnapBehavior alloc] initWithItem:self.redView snapToPoint:location];

//阻尼,减幅,衰减 取值(0-1)

snap.damping = 0;

//3 把行为添加到物理仿真器

[self.animator addBehavior:snap];

 

 

 

 

五、附着行为(Attachment)

1. 附着行为描述一个视图与一个锚点或者另一个视图相连接的情况附着 行为描述的是两点之间的连接情况,可以模拟刚性或者弹性连接在多 个物体间设定多个UIAttachmentBehavior,可以模拟多物体连接

2. 演示附着行为

3. 演示附着行为-连线

4. 演示附着行为-刚性行为和弹性行为

5. 演示附着行为-和红色的左上角连接

6. 属性:

attachedBehaviorType:连接类型(连接到锚点或视图)

items:连接视图数组

anchorPoint:连接锚点

length:距离连接锚点的距离

只要设置了以下两个属性,即为弹性连接

damping:振幅大小

frequency:振动频率

7. 示例代码

//1 物理仿真器

self.animator = [[UIDynamicAnimator alloc]

                 initWithReferenceView:self.view];

//2 重力行为

UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:

  @[self.redView]];

[gravity setAction:^{

    view.startPoint = self.redView.center;

    view.endPoint = point; }];

//2.1 添加附着行为

UIAttachmentBehavior *attachment = [[UIAttachmentBehavior alloc] initWithItem:self.redView attachedToAnchor:point];

//弹性行为 (取值范围:0---1

attachment.frequency = 0.5;

attachment.damping = 0.5;

//3 把行为添加到仿真器

[self.animator addBehavior:gravity];

[self.animator addBehavior:attachment];

 

 

 

 

六、推动行为(Push)

1. 推行为可以为一个视图施加一个作用力,该力可以是持续的,也可以是一次性的可以设置力的大小,

向和作用点等信息

2. 属性: mode:推动类型(一次性或是持续推) angle:推动角度

magnitude:推动力量

3. 演示推动行为

4. 演示推动行为-点击界面推动

5. 示例代码

//1 物理仿真器

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

//2 一次性推动行为(持续性推动行为)

UIPushBehavior *push = [[UIPushBehavior alloc] initWithItems:@[self.redView]

                                                        mode:UIPushBehaviorModeContinuous];

//

//设置推动的方向和推力的大小

push.angle = M_PI_2;

push.magnitude = 1;

//设置向量

push.pushDirection = CGVectorMake(0, 100);

//3 把推动行为添加都物理仿真器

[self.animator addBehavior:push];

 

 

 

 

 

七、UIDynamicItemBehavior

1. UIDynamicItemBehavior:元素行为

DynamicItem是一个辅助的行为,用来设置运动学元素参与物理仿真过程中的参数,: 性系数、摩擦系数、密度、阻力、角阻力以及是否允许旋转等

elasticity(弹性系数):决定了碰撞的弹性程度,比如碰撞时物体的弹性

friction(摩擦系数) :决定了沿接触面滑动时的摩擦力大小

density(密度): size结合使用,计算物体的总质量。质量越大,物体加速或减速就越 困难

resistance(阻力):决定线性移动的阻力大小,与摩擦系数不同,摩擦系数只作用于滑动 运动

angularResistance(角阻力) :决定旋转运动时的阻力大小

allowsRotation(允许旋转):这个属性很有意思,它在真实的物理世界没有对应的模型。 设置这个属性为 NO 物体就完全不会转动,而无论施加多大的转动力

 

 

 

八、毛毛虫案例

1. 搭建项目,实现以下样子

    a.创建毛毛虫视图 (用懒加载的方式创建 然后放到数组中)

    //示例代码

//懒加载虫子

- (NSArray *)wormViews

{

    if (_wormViews == nil)

    {

        // 1. 新建9个视图

        CGFloat startX = 20;

        CGFloat startY = 80;

        CGFloat r = 10;

        

        NSMutableArray *arrayM = [NSMutableArray arrayWithCapacity:9];

        

        for (NSInteger i = 0; i < 9; i++) {

            

            UIView *view = [[UIView alloc] initWithFrame:CGRectMake(startX + i * 2 * r, startY, 2 * r, 2 * r)];

            view.backgroundColor = [UIColor blueColor];

            view.layer.cornerRadius = r;

            

            if (i == 8) {

                view.frame = CGRectMake(startX + i * 2 * r, startY - r, 4 * r, 4 * r);

                view.layer.cornerRadius = 2 * r;

                

                view.backgroundColor = [UIColor greenColor];

            }

            

            [self.view addSubview:view];

            

            [arrayM addObject:view];

        }

        _wormViews = arrayM;

    }

    return _wormViews;

}

 

    b.特殊处理虫子头部

//虫子

self.headView = self.wormViews.lastObject;

 

2. 添加物理仿真行为

创建动画着对象

//1.创建动画者

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

 

a. 添加虫子view的附着行为

// 2.1 创建附着行为

for (int i = 0; i < self.wormViews.count - 1; i++) {

    

    UIAttachmentBehavior *attachment = [[UIAttachmentBehavior alloc] initWithItem:self.wormViews[i] attachedToItem:self.wormViews[i + 1]];

    

    [self.animator addBehavior:attachment];

}

 

b. 添加重力行为

// 2.2 添加重力行为

UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:self.wormViews];

 

[self.animator addBehavior:gravity];

 

c. 添加碰撞行为

// 2.3 添加碰撞行为和边界

UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:self.wormViews];

collision.translatesReferenceBoundsIntoBoundary = YES;

 

[self.animator addBehavior:collision];

 

d.添加拖拽手势事件 (也可以是触摸事件)

 

// 拖动手势

UIGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];

[self.view addGestureRecognizer:pan];

 

- (void)pan:(UIPanGestureRecognizer *)recognizer

{

    CGPoint location = [recognizer locationInView:self.view];

    

    if (UIGestureRecognizerStateBegan == recognizer.state) {

        // 实例化一个附加行为,拖脑袋

        UIAttachmentBehavior *attachment = [[UIAttachmentBehavior alloc] initWithItem:self.headView attachedToAnchor:location];

        

        [_animator addBehavior:attachment];

        

        self.attachment = attachment;

    } else if (UIGestureRecognizerStateChanged == recognizer.state) {

        // 移动

        

        self.attachment.anchorPoint = location;

        

    } else if (UIGestureRecognizerStateEnded == recognizer.state) {

        // 把虫子扔地上

        [self.animator removeBehavior:self.attachment];

    }

}

 

 

 

 

 

 

 

 

 

 

 

© 著作权归作者所有

共有 人打赏支持
上一篇: NSOperation
工匠心
粉丝 7
博文 44
码字总数 43071
作品 0
东城
私信 提问
【iOS】UIDynamic

UIDynamic是从iOS 7开始引入的一种新技术,属于UIKit框架。可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象:如重力、弹性碰撞等现象。 一、UIDynamic中的一些概念 三个重要的类:...

xn4545945
2014/07/30
0
0
Swift3.0 UIDynamic仿真器,物理引擎

在OC上使用UIDynamic和Swift3.0 差不多一样的方法,可能UIDynamic已经够简洁,但是要写出棒棒哒的效果还是需要很多的组合行为才能实现。 我这里全当抛砖引玉 最后祝大家圣诞快乐!!!...

大_瓶_子
2016/12/23
0
0
AugustRush/Stellar

A fantastic Physical animation library for swift(Not Just Spring !!!), it is base on UIDynamic and extension to it, friendly APIs make you use it or custom your own animation ve......

AugustRush
2016/07/02
0
0
iOS开发之UIDynamic

1、概述 什么是UIDynamic? UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架。 可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象。比如:重力、弹性碰撞等现象。 物理引...

feng_blog
2015/08/31
0
0
UIDynamic——UIKit动力学

简介 UIKit动力学最大的特点是将现实世界动力驱动的动画引入了UIKit,比如重力,铰链连接,碰撞,悬挂等效果,即将2D物理引擎引入了UIKit 注意:UIKit动力学的引入,并不是为了替代CA或者UIV...

工匠心
2016/03/15
19
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周一乱弹 —— 白掌柜说了卖货不卖身

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @爱漫爱 :这是一场修行分享羽肿的单曲《Moony》 手机党少年们想听歌,请使劲儿戳(这里) @clouddyy :开不开心? 开心呀, 我又不爱睡懒觉…...

小小编辑
今天
8
0
大数据教程(11.7)hadoop2.9.1平台上仓库工具hive1.2.2搭建

上一篇文章介绍了hive2.3.4的搭建,然而这个版本已经不能稳定的支持mapreduce程序。本篇博主将分享hive1.2.2工具搭建全过程。先说明:本节就直接在上一节的hadoop环境中搭建了! 一、下载apa...

em_aaron
今天
3
0
开始看《JSP&Servlet学习笔记》

1:WEB应用简介。其中1.2.1对Web容器的工作流程写得不错 2:编写Servlet。搞清楚了Java的Web目录结构,以及Web.xml的一些配置作用。特别是讲了@WebServlet标签 3:请求与响应。更细致的讲了从...

max佩恩
今天
4
0
mysql分区功能详细介绍,以及实例

一,什么是数据库分区 前段时间写过一篇关于mysql分表的的文章,下面来说一下什么是数据库分区,以mysql为例。mysql数据库中的数据是以文件的形势存在磁盘上的,默认放在/mysql/data下面(可...

吴伟祥
今天
3
0
SQL语句查询

1.1 排序 通过order by语句,可以将查询出的结果进行排序。放置在select语句的最后。 格式: SELECT * FROM 表名 ORDER BY 排序字段ASC|DESC; ASC 升序 (默认) DESC 降序 1.查询所有商品信息,...

stars永恒
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部