AJ学IOS 之UIDynamic重力、弹性碰撞吸附等现象
AJ分享,必须精品
一:效果
重力和碰撞
吸附现象
二:简介
什么是UIDynamic
UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架
可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象
重力、弹性碰撞等现象
物理引擎的价值
广泛用于游戏开发,经典成功案例是“愤怒的小鸟”
让开发人员可以在远离物理学公式的情况下,实现炫酷的物理仿真效果
提高了游戏开发效率,产生更多优秀好玩的物理仿真游戏
知名的2D物理引擎
Box2d
Chipmunk
三:使用步骤和代码
步骤
要想使用UIDynamic来实现物理仿真效果,大致的步骤如下
1,创建一个物理仿真器(顺便设置仿真范围)。
2,创建相应的物理仿真行为(顺便添加物理仿真元素)。
3,将物理仿真行为添加到物理仿真器中 开始仿真。
简单认识
物理仿真元素(Dynamic Item)谁要进行物理仿真?
物理仿真行为(Dynamic Behavior) 执行怎样的物理仿真效果?怎样的动画效果?
物理仿真器(Dynamic Animator)让物理仿真元素执行具体的物理仿真行为
注意:
不是任何对象都能做物理仿真元素。
不是任何对象都能进行物理仿真。
任何遵守了UIDynamicItem协议的对象才能做物理仿真元素。
UIView默认已经遵守了UIDynamicItem协议,因此任何UI控件都能做物理仿真。
UICollectionViewLayoutAttributes类默认也遵守UIDynamicItem协议。
UIDynamic提供了以下几种物理仿真行为
UIGravityBehavior:重力行为
UICollisionBehavior:碰撞行为
UISnapBehavior:捕捉行为
UIPushBehavior:推动行为
UIAttachmentBehavior:附着行为
UIDynamicItemBehavior:动力元素行为
物理仿真行为须知
上述所有物理仿真行为都继承自UIDynamicBehavior
所有的UIDynamicBehavior都可以独立进行
组合使用多种行为时,可以实现一些比较复杂的效果
物理仿真器
它可以让物理仿真元素执行物理仿真行为
它是UIDynamicAnimator类型的对象
UIDynamicAnimator的初始化
- (instancetype)initWithReferenceView:(UIView *)view;
view参数:是一个参照视图,表示物理仿真的范围
UIDynamicAnimator的常见方法
- (void)addBehavior:(UIDynamicBehavior *)behavior;
添加1个物理仿真行为
- (void)removeBehavior:(UIDynamicBehavior *)behavior;
移除1个物理仿真行为
- (void)removeAllBehaviors;
移除之前添加过的所有物理仿真行为
UIDynamicAnimator的常见属性
@property (nonatomic, readonly) UIView* referenceView;
参照视图
@property (nonatomic, readonly, copy) NSArray* behaviors;
添加到物理仿真器中的所有物理仿真行为
@property (nonatomic, readonly, getter = isRunning) BOOL running;
是否正在进行物理仿真
@property (nonatomic, assign) id <UIDynamicAnimatorDelegate> delegate;
代理对象(能监听物理仿真器的仿真过程,比如开始和结束)
代码
演示效果小应用的实现代码
#import "HMViewController.h"
@interface HMViewController ()
/**
* 红色view
*/
@property (weak, nonatomic) IBOutlet UIView *redView;
/**
* 物理仿真器
*/
@property (nonatomic, strong) UIDynamicAnimator *anim;
@property (weak, nonatomic) IBOutlet UISegmentedControl *st;
@end
@implementation HMViewController
- (UIDynamicAnimator *)anim
{
if (!_anim) {
_anim = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
}
return _anim;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// [self test];
// [self test2];
[self test3:touches];
}
-(void)test3:(NSSet *)touches
{
// 1.获取当前触摸的手指
UITouch *touch = [touches anyObject];
// 2.更具手指取出位置
CGPoint point = [touch locationInView:touch.view];
// 吸附行为
// 1.创建物理仿真器
// 2.创建物理仿真行为
UISnapBehavior *snapB = [[UISnapBehavior alloc] initWithItem:self.redView snapToPoint:point];
// 设置吸附行为的"减震"
snapB.damping = 0;
// 注意: 吸附行为默认只能吸附一次, 如果多次吸附必须从仿真器中移除再重新添加
[self.anim removeAllBehaviors];
// 3.将物理仿真行为添加到仿真器中
[self.anim addBehavior:snapB];
}
- (void)test2
{
// 碰撞
// 1.创建物理仿真器
// 2.创建物理仿真行为
UIGravityBehavior *gravigtyB = [[UIGravityBehavior alloc] initWithItems:@[self.redView]];
// gravigtyB.magnitude = 100;
// 创建碰撞仿真行为
UICollisionBehavior *collisionB = [[UICollisionBehavior alloc] initWithItems:@[self.redView, self.st]];
// 设置碰撞的边界
// collisionB.translatesReferenceBoundsIntoBoundary = YES;
// 添加直线边界
// [collisionB addBoundaryWithIdentifier:@"line" fromPoint:CGPointMake(0, 200) toPoint:CGPointMake(320, 420)];
// 添加图形的边界
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:self.view.frame];
[collisionB addBoundaryWithIdentifier:@"abc" forPath:path];
// 3.将物理仿真行为添加到仿真器中
[self.anim addBehavior:gravigtyB];
[self.anim addBehavior:collisionB];
}
/**
* 重力
*/
- (void)test
{
// 演示重力行为
// 1.创建物理仿真器
// 并且指定了当前控制器的view作为仿真范围
// UIDynamicAnimator *anim = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
// 2.创建物理仿真行为
// 并且指定红色为作为仿真元素
UIGravityBehavior *gravityB = [[UIGravityBehavior alloc] initWithItems:@[self.redView]];
// 设置重力的方向
// gravityB.gravityDirection = CGVectorMake(1, 0);
// gravityB.gravityDirection = CGVectorMake(0, -1);
// gravityB.gravityDirection = CGVectorMake(1, 1);
// 设置重力的角度
// gravityB.angle = M_PI_2;
// 设置重力的加速度
gravityB.magnitude = 100.0;
// 3.将物理仿真行为添加到仿真器中
[self.anim addBehavior:gravityB];
}
@end
AJ学IOS 之UIDynamic重力、弹性碰撞吸附等现象的更多相关文章
- (素材源代码) 猫猫学iOS 之UIDynamic重力、弹性碰撞吸附等现象牛逼Demo
猫猫分享,必须精品 原创文章,欢迎转载. 转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 一:效果 二:代码 #import "ViewCon ...
- AJ学IOS 之微博项目实战(2)微博主框架-自定义导航控制器NavigationController
AJ分享,必须精品 一:添加导航控制器 上一篇博客完成了对底部的TabBar的设置,这一章我们完成自定义导航控制器(NYNavigationController). 为啥要做自定义呢,因为为了更好地封 ...
- AJ学IOS(13)UI之UITableView学习(下)汽车名牌带右侧索引
AJ分享,必须精品 先看效果图 代码 ViewController #import "NYViewController.h" #import "NYCarGroup.h& ...
- AJ学IOS 之微博项目实战(1)微博主框架-子控制器的添加
AJ分享,必须精品 一:简单介绍 这是新浪微博的iOS端项目,来自于黑马的一个实战项目. 主要分成五大模块,本次全部运用纯代码实现,其中会用到很多前面学过得内容,如果有的地方有重复的知识点,说明这个知 ...
- AJ学IOS(56)网络基础以及如何搭建服务器
AJ分享,必须精品 一:为什么要学习网络编程 关于这个问题,为什么要学习网络编程,AJ的理解就是,这东西是时代发展的必要,没什么为什么,就是应该学,除非你就是想玩单机,但是就算是单机也会有购买金币之类 ...
- AJ学IOS(55)多线程网络之图片下载框架之SDWebImage
AJ分享,必须精品 效果: 代码: - (NSArray *)apps { if (!_apps) { NSArray *dictArray = [NSArray arrayWithContentsO ...
- AJ学IOS(49)多线程网络之线程的创建NSThreand
AJ分享,必须精品 一:NSThread的基本使用 1:创建和启动线程 一个NSThread对象就代表一条线程 创建.启动线程 NSThread *thread = [[NSThread alloc] ...
- AJ学IOS(42)UI之核心动画CAAnimationGroup以及其他
AJ分享,必须精品 效果: 代码: 很简单,不多说,就是把一堆动画放一起,看代码. - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent * ...
- AJ学IOS(01) UI之Hello World与加法计算器
不多说,AJ分享,必须精品 这两个一个是HelloWorld(左边) 另一个是 加法计算器(右边)的截图. 先运行第一个 程序看看效果 1.打开Xcode(没有哦mac系统的没有xcode的帮你们默哀 ...
随机推荐
- connection closed by foreign host / Permissions 0620 for '/etc/ssh/ssh_host_ed25519_key' are too open 解决方案
发生此次故障的原因: 在文件夹授权时 错误的执行了 chmod -R 755 / 本来只想授权当前文件夹的 结果... 然后就导致xshell连不上了 懵逼... 解决方案 将权限收回: 执行: ch ...
- SQL语句中,如何使用含有if....else...判断语句
在我们开发中,有时要对数据库中的数据按照条件进行查询,用到if else类似的语句进行判断,那么if else语句只有在存储过程,触发器之类的才有,但是要在sql上当满足某种条件上要取不同的字段值,刚 ...
- SQL数据库-基本操作
SQL教程 整理自:廖雪峰的官方网站-SQL教程 目录 SQL教程 SQL快捷键 1.概述 数据类型 SQL操作数据库的能力 语法特点 2. 安装MySQL 运行MySQL 3. 关系模型 3.1 概 ...
- java基础-对集合(Collection)的总结
集合(Collection)类型也是Java标准库中被使用最多的类型. List ArrayList LinkedList 对于自定义的对象,需要正确覆写 equals方法 参看7.3 例子 Map ...
- 嘉泽 P2120: 【基础】半质数 题解
原题链接 简要题意: 求区间内能分解为两个质数乘积的数. 欧拉筛先筛素数. 然后再筛答案. 时间复杂度: \(O(n)\). 实际得分:\(100pts\). #pragma GCC optimize ...
- 从字节码来分析,i++与++i区别
++/-- 是一种特殊的算术运算符,在算术运算符中需要两个操作数来进行运算,而自增自减运算符是一个操作数 前缀自增(++a):先进行自增运算,再进行表达式运算: 后缀自增(a++):先进行表达式运算, ...
- 我们是怎么实现Grpc CodeFirst
前言: Grpc默认是ProtoFirst的,即先写 proto文件,再生成代码,需要人工维护proto,生成的代码也不友好,所以出现了Grpc CodeFirst,下面来说说我们是怎么实现Grpc ...
- Leetcode_474. 一和零(二维01背包)
每个字符串看成一个物品,两个属性是0和1的个数,转换为01背包. code class Solution { public: int w[605][2]; int dp[105][105]; int ...
- Magento2(麦进斗) docker 安装
Magento 介绍 Magento(麦进斗)是一套专业开源的电子商务系统,采用php进行开发,使用Zend Framework框架.Magento设计得非常灵活,具有模块化架构体系和丰富的功能.易于 ...
- openfire广播broadcast插件怎么发送消息给所有用户(包括在线和离线)
openfire广播broadcast插件怎么发送消息给所有用户(包括在线和离线): 打开openfire管理界面,找到服务器系统属性,添加一个属性(属性名:plugin.broadcast.all2 ...