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的帮你们默哀 ...
随机推荐
- Integration of Metabolomics and Transcriptomics To Reveal Metabolic Characteristics and Key Targets Associated with Cisplatin Resistance in Nonsmall Cell Lung Cancer(解读人:林山云)
期刊名:J. Proteome Res 发表时间:(2019年8月) IF:3.78 单位: 上海第九人民医院药学系,上海交通大学药学院 上海交通大学药物与生物化学系 物种:人源A549细胞系 技 ...
- AspNetCore3.1_Secutiry源码解析_6_Authentication_OpenIdConnect
title: "AspNetCore3.1_Secutiry源码解析_6_Authentication_OpenIdConnect" date: 2020-03-25T21:33: ...
- AdFind
C++实现(未开源),用于查询域内信息 http://www.joeware.net/freetools/tools/adfind/index.htm 常用命令如下: 列出域控制器名称: AdFind ...
- 补充《解析“60k”大佬的19道C#面试题(上)》
[广州.NET技术俱乐部]微信群的周杰写了一篇文章<解析“60k”大佬的19道C#面试题(上)>https://www.cnblogs.com/sdflysha/p/20200325-19 ...
- CTF_WriteUp_HTTP基本认证(Basic access authentication)
HTTP基本认证 在HTTP中,基本认证(英语:Basic access authentication)是允许http用户代理(如:网页浏览器)在请求时,提供用户名和密码 的一种方式.HTTP基本认证 ...
- 面试刷题17:线程两次start()会发生什么?
线程是并发编程的基础元素,是系统调度的最小单元,现代的jvm直接对应了内核线程.为了降低并发编程的门槛,go语言引入了协程. 你好,我是李福春,我在准备面试,今天的题目是? 一个线程两次调用start ...
- 洛谷P1003 铺地毯 模拟
这一题就是一个很普通的模拟,每次输入的时候存储四个角的值 把四个角的横纵坐标存储在一排.然后在倒序遍历一遍,查找的时候就看所要查找的坐标在不在这个范围内,如果找到了就标记一下再输出,如果没有找到就输出 ...
- Mock测试,结合Fiddler轻松搞定不同场景
在平时测试过程中,总会遇到一些比较难构造的场景.比如不同平台间的同步,异常场景的构造.遇到难构造的场景时,就可以引用Mock来进行单元测试.简言之:mock测试就是在测试过程中,对于某些不容易构造或者 ...
- CF 1012C Dp
Welcome to Innopolis city. Throughout the whole year, Innopolis citizens suffer from everlasting cit ...
- java新时间类
时间 java8以前使用的时间很多方法都已经废弃了,而且不是线程安全的,java8提供了一系列的时间类,这些时间类都是线程安全的 LocalDate.LocalTime.LocalDateTime 这 ...