文档章节

UIDynamic

工匠心
 工匠心
发布于 2016/05/22 08:38
字数 2393
阅读 17
收藏 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
东城
私信 提问
摆球碰撞运动效果--DynamicBehavior

利用UIDynamic模拟现实世界中的摆球碰撞运动效果。 对于一些真实世界中的动画行为,碰撞啊之类,实现起来特别复杂,而UIDynamic的引入就是为了简化这一类动画行为的。其将现实世界中各种物理...

红薯
2014/07/15
305
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
UIDynamicExample

iOS 7中引入了UIDynamic behavior 的概念,用于模拟物理世界中物体的一些物理效果。这份Demo演示了如何使用UIDynamicAnimator来模拟一些常见的物理效果。 [Code4App.com]...

红薯
2013/12/27
338
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

没有更多内容

加载失败,请刷新页面

加载更多

小白带你认识netty(三)之NioEventLoop的线程(或者reactor线程)启动(一)

在第一章中,我们看关于NioEventLoopGroup的初始化,我们知道了NioEventLoopGroup对象中有一组EventLoop数组,并且数组中的每个EventLoop对象都对应一个线程FastThreadLocalThread,那么这个...

天空小小
今天
3
0
PHP动态扩展Redis模块

查看已有模块 [root@test-a ~]# /usr/local/php/bin/php -m[PHP Modules]bz2Core...zlib[Zend Modules] 下载包,解压,生成configure文件 [root@test-a ~]# cd /usr/local/src/[ro......

野雪球
今天
4
0
在Ignite中使用线性回归算法

在本系列前面的文章中,简单介绍了一下Ignite的机器学习网格,下面会趁热打铁,结合一些示例,深入介绍Ignite支持的一些机器学习算法。 如果要找合适的数据集,会发现可用的有很多,但是对于...

李玉珏
今天
5
0
Mybatis应用学习——简单使用示例

1. 传统JDBC程序中存在的问题 1. 一个简单的JDBC程序示例: public class JDBCDemo {public static void main(String[] args) {Connection con=null;PreparedStatement statemen...

江左煤郎
今天
5
0
使用JavaScript编写iOS应用业务逻辑

JSAUIKitCocoa使你可以使用JavaScript编写对性能要求不高但可能变动性很大的iOS应用的业务逻辑部分,View组件、需要多线程支持的Model等则直接使用原生对象。 编写方式与React Native相似,但...

neal01
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部