Swift中的UIKit重力学
前言:
重力学这个名词不论在哪个行业领域听起来似乎都非常高大上。
那么在Swift中的重力学是什么呢?那就是将我们移动端屏幕上毫无生命力的东西也置于万有引力中。使它们能够展现出好像真的因为引力而向下坠落以及碰到物体后自然的弹开的效果。
要想做到这一点,我们得须要两个利器:UIKit Dynamics和Motion Effects。
一、简介
1.UIKit Dynamics是从iOS 7開始引入的一种新技术,隶属于UIKit框架的物理引擎。能模拟和仿真现实生活中的物理现象它能够让我们在程序中对界面元素加入一些行为从而达到诸如重力、弹簧等现实中的动作行为。你仅仅需在引擎中注冊界面元素,并指定好物理行为,其它的事就交给物理引擎去完毕了。
• Motion Effects能够创建非常酷的视差效果。就像你iPhone上横竖屏切换时那样。它基于Apple提供的重力加速器提供的数据计算分析,使我们的界面元素依据移动设备的倾斜方向做出相应的反应。
2.物理引擎的价值
广泛用于游戏开发,经典成功案例是“愤慨的小鸟”
让开发者能够在远离物理学公式的情况下。实现炫酷的物理仿真效果
提高了游戏开发效率,产生很多其它优秀好玩的物理仿真游戏
3.知名的2D物理引擎
Box2d
Chipmunk
二、使用步骤
要想使用UIDynamic来实现物理仿真效果。大致的过程例如以下
(1)创建一个物理仿真器(顺便设置仿真范围)
(2)创建相应的物理仿真行为(顺便加入物理仿真元素)
(3)将物理仿真行为加入到物理仿真器中 開始仿真
三、相关说明
1.三个概念
(1)谁要进行物理仿真?
物理仿真元素(Dynamic Item)
(2)运行如何的物理仿真效果?如何的动画效果?
物理仿真行为(Dynamic Behavior)
(3)让物理仿真元素运行详细的物理仿真行为
物理仿真器(Dynamic Animator)
2.物理仿真元素
注意:不是不论什么对象都能做物理仿真元素
不是不论什么对象都能进行物理仿真
物理仿真元素要素:
不论什么遵守了UIDynamicItem协议的对象
UIView默认已经遵守了UIDynamicItem协议,因此不论什么UI控件都能做物理仿真
UICollectionViewLayoutAttributes类默认也遵守UIDynamicItem协议
3.物理仿真行为
(1)UIDynamic提供了下面几种物理仿真行为
动力行为能够在随意时间内进行加入或移除。
另外动力行为能够是组合的,也能够被继承。能够通过向UIDynamicBehavior或者用户子类化的 UIDynamicBehavior的实例使用addChildBehavior: 方法创建组合行为。(但不能向系统提供的行为使用该方法)
1.吸附行为(UIAttachmentBehavior):有一个对象UIAttachmentBehavior, 该对象用来指定两个动力项(项或点)之间的连接,当一个项或者点移动时,吸附的项也随之移动。当然,这个连接并非全然是静态的(static),吸附的 项有两个属性damping(阻尼)和oscillation(震荡)。这两个属性决定了吸附项的行为是如何随时间而变化的。
(1)UIAttachmentBehavior
指定两个动力项或者动力项和锚点间的连接。动力项默认锚点在他的center。
步骤1.使用initWithItem:方法实例化UIAttachmentBehavior
2.使用addBehavior: 方法将行为加入到动力动画。
能够加入到自己定义的组合行为,假设想在动力动画的每一步改变行为,能够实现继承的 action 方法。
(2)UIAttachmentBehavior实例化方法
convenience init!(item: UIDynamicItem, attachedToAnchor point: CGPoint) //实例化UIAttachmentBehavior,连接dynamic item的center到一个锚点。
convenience init!(item: UIDynamicItem, offsetFromCenter offset: UIOffset, attachedToAnchor point: CGPoint)//实例化UIAttachmentBehavior,连接dynamic item的指定点(相对于dynamic item center的点)到一个锚点。
convenience init!(item item1: UIDynamicItem, attachedToItem item2: UIDynamicItem) //实例化UIAttachmentBehavior,连接dynamic item的center到还有一个dynamic item的center。
init!(item item1: UIDynamicItem, offsetFromCenter offset1: UIOffset, attachedToItem item2: UIDynamicItem, offsetFromCenter offset2: UIOffset)//实例化UIAttachmentBehavior,连接 dynamic item的指定点(相对于dynamic item center的点)到还有一个dynamic item的指定点。
(3)UIAttachmentBehavior经常使用属性:
var items: [AnyObject] { get } //返回行为连接的dynamic items。
var attachedBehaviorType: UIAttachmentBehaviorType { get }//UIAttachmentBehavior的类型。枚举(UIAttachmentBehaviorType.Items,.Anchor)
var anchorPoint: CGPoint // 锚点类型UIAttachmentBehavior的锚点。
var length: CGFloat //两个吸附点间的距离(浮点)
var damping: CGFloat // 1: 阻尼数值(浮点) critical(临界值) damping
var frequency: CGFloat // 震动频率(浮点)in Hertz(单位赫兹)
2.碰撞行为(UICollisionBehavior):通过对象UICollisionBehavior指定一个边界,而且让各个动力项,在该边界内參与碰撞。
UICollisionBehavior对象还能够指定这些动力项适当的回应碰撞。
(1)UICollisionBehavior
指定一些dynamic item能够相互碰撞或者与UICollisionBehavior的界线碰撞。
步骤1.使用init方法创建UICollisionBehavior, 使用addItem: 方法向其加入dynamic item 或者使用initWithItems:实例化UICollisionBehavior。
2. 使用addBehavior: 方法将UICollisionBehavior加入到动力动画
(2)UICollisionBehavior实例化方法及管理:
init!(items: [AnyObject])//使用dynamic item数组实例化UICollisionBehavior
func addItem(item: UIDynamicItem) //向UICollisionBehavior实例加入dynamic item
func removeItem(item: UIDynamicItem)//删除dynamic item
var items: [AnyObject] { get }//返回UICollisionBehavior实例中的dynamic item数组
var collisionMode: UICollisionBehaviorMode //指定碰撞类型
static var Items: UICollisionBehaviorMode { get }
static var Boundaries: UICollisionBehaviorMode { get }
static var Everything: UICollisionBehaviorMode { get }
var translatesReferenceBoundsIntoBoundary: Bool // 基于相对坐标系统的界线是否有效
UICollisionBehavior设置界线的三种方法:
func setTranslatesReferenceBoundsIntoBoundaryWithInsets(insets: UIEdgeInsets)(前提使用reference view 或者 collection view layout实例化的动力动画)注意: dynamic item的初始位置不能在界线外
func addBoundaryWithIdentifier(identifier: NSCopying, forPath bezierPath: UIBezierPath)
func addBoundaryWithIdentifier(identifier: NSCopying, fromPoint p1: CGPoint, toPoint p2: CGPoint)
func boundaryWithIdentifier(identifier: NSCopying) -> UIBezierPath?//返回指定标示符相应的贝塞尔曲线界线
func removeBoundaryWithIdentifier(identifier: NSCopying)//移除指定标示符相应的贝塞尔曲线界线
var boundaryIdentifiers: [AnyObject]? { get }//返回UICollisionBehavior 实例的全部界线标示符
func removeAllBoundaries()
unowned(unsafe) var collisionDelegate: UICollisionBehaviorDelegate? //实例的collisionDelegate会响应 碰撞的一些回调方法
3.重力行为(UIGravityBehavior):通过对象UIGravityBehavior给动力项指定一个重力矢量,具有重力矢量的动力项,会在重力矢量的方向上一直加速。直到与别的动力项产生了冲突或者。遇到了边界。
(1) UIGravityBehavior实例化方法及管理:
init(items: [AnyObject])//使用dynamic item数组实例化UIGravityBehavior
func addItem(item: UIDynamicItem)//向UIGravityBehavior实例加入dynamic item
func removeItem(item: UIDynamicItem)//移除UIGravityBehavior实例的dynamic item
var items: [AnyObject] { get }//返回UIGravityBehavior实例中的dynamic item数组
// The default value for the gravity vector is (0.0, 1.0)
// The acceleration for a dynamic item subject to a (0.0, 1.0) gravity vector is downwards at 1000 points per second².
var gravityDirection: CGVector //航行的方向,趋势(范围是(0.0, 1.0))
var angle: CGFloat// 角度
var magnitude: CGFloat// 速率 angle的值为0时,方块会水平向右移动。随着值的增大,方块会顺时针改变角度。只是我们要模拟现实中的重力。所以该属性一般不设置,不设置时默认是垂直向下移动。magnitude是重力行为的速率属性,值越大下降的速度越快,当magnitude属性的值为0时,方块就不会下降了,所以最小的速率是0.1。
func setAngle(angle: CGFloat, magnitude: CGFloat)//角度和速率一起设置
4.推动行为(UIPushBehavior):通过对象UIPushBehavior给动力项指定一个持续的或者瞬时的力(force vector)。
(1) UIPushBehavior实例化方法及管理:
init!(items: [AnyObject]!, mode: UIPushBehaviorMode)
func addItem(item: UIDynamicItem)
func removeItem(item: UIDynamicItem)
var items: [AnyObject] { get }
func targetOffsetFromCenterForItem(item: UIDynamicItem) -> UIOffset // 偏移
func setTargetOffsetFromCenter(o: UIOffset, forItem item: UIDynamicItem)
var mode: UIPushBehaviorMode { get } // 推送的模式
var active: Bool // 是否活动
var angle: CGFloat // 角度
// A continuous force vector with a magnitude of 1.0, applied to a 100 point x 100 point view whose density value is 1.0, results in view acceleration of 100 points per s^2
var magnitude: CGFloat //速率
var pushDirection: CGVector //推送的航向趋势
func setAngle(angle: CGFloat, magnitude: CGFloat) //设置角度和速率
5.捕捉行为(UISnapBehavior):通过对象UISnapBehavior给动力项指定一个捕捉点。动力项会依据配置的效果,来抓住这一捕捉点。
(1) UISnapBehavior实例化方法及管理
// The point argument is expressed in the reference coordinate system
init!(item: UIDynamicItem, snapToPoint point: CGPoint)
var damping: CGFloat // damping value from 0.0 to 1.0. 0.0 is the least oscillation.
6.动力元素行为(UIDynamicItemBehavior)
(1) UIDynamicItemBehavior
步骤1.使用init方法创建UICollisionBehavior,使用addItem: 方法向其加入dynamic item 或者使用initWithItems:实例化UIDynamicItemBehavior。
2. 使用addBehavior: 方法将UIDynamicItemBehavior加入到动力动画
(2) UIDynamicItemBehavior实例化方法及管理:
init(items: [AnyObject])
func addItem(item: UIDynamicItem)
func removeItem(item: UIDynamicItem)
var items: [AnyObject] { get }
var elasticity: CGFloat // 设置碰撞弹性系数。
范围(0.0-1.0)
var friction: CGFloat // 设置摩擦系数。
var density: CGFloat // 设置相对密度 1 by default
var resistance: CGFloat // 线性阻力系数。
(0--CGFLOAT_MAX)
var angularResistance: CGFloat // 设置角度阻力系数(0--CGFLOAT_MAX)
var allowsRotation: Bool // 设置行为中的dynamic item能否够循环
// The linear velocity, expressed in points per second, that you want to add to the specified dynamic item
// If called before being associated to an animator, the behavior will accumulate values until being associated to an animator
func addLinearVelocity(velocity: CGPoint, forItem item: UIDynamicItem)//向dynamic item添加线速度属性。单位点
func linearVelocityForItem(item: UIDynamicItem) -> CGPoint
// The angular velocity, expressed in radians per second, that you want to add to the specified dynamic item
// If called before being associated to an animator, the behavior will accumulate values until being associated to an animator
func addAngularVelocity(velocity: CGFloat, forItem item: UIDynamicItem)//向dynamic item添加角速度属性。单位弧度
func angularVelocityForItem(item: UIDynamicItem) -> CGFloat
注意: 假设向同一个动力动画加入多个UIDynamicItemBehavior实例。仅仅会应用一套属性描写叙述(交集?)多个UIDynamicItemBehavior实例配置同个属性时,使用最后的。
(2)物理仿真行为须知
上述全部物理仿真行为都继承自UIDynamicBehavior
UIDynamicBehavior配置:
func addChildBehavior(behavior: UIDynamicBehavior!)//向自己定义的UIDynamicBehavior加入子行为
func removeChildBehavior(behavior: UIDynamicBehavior)//删除自己定义的UIDynamicBehavior的子行为
var childBehaviors: [AnyObject] { get }//返回自己定义UIDynamicBehavior的子行为数组
// When running, the dynamic animator calls the action block on every animation step.
var action: (() -> Void)!//在UIDynamicAnimator运行过程中每一步都会调用的语句块
func willMoveToAnimator(dynamicAnimator: UIDynamicAnimator?) // nil when being removed from an animator
var dynamicAnimator: UIDynamicAnimator? { get }
4.物理仿真器
(1)物理仿真器须知
它能够让物理仿真元素运行物理仿真行为
它是UIDynamicAnimator类型的对象
• 提供动力行为的上下文
• 依据ref view确定坐标系
• 控制动力引擎
• 维护着动力行为的状态
(2)UIDynamicAnimator的初始化
init(referenceView view: UIView)
view參数:是一个參照视图。表示物理仿真的范围
(3)UIDynamicAnimator的常见方法
func addBehavior(behavior: UIDynamicBehavior!)//加入1个物理仿真行为
func removeBehavior(behavior: UIDynamicBehavior!)//移除1个物理仿真行为
func removeAllBehaviors()//移除之前加入过的全部物理仿真行为
func itemsInRect(rect: CGRect) -> [AnyObject]//返回贯穿指定区域的全部dynamic item。
func elapsedTime() -> NSTimeInterval//返回动画開始到如今的时间间隔。
func updateItemUsingCurrentState(item: UIDynamicItem)//(更新dynamic item在UIDynamicAnimator内部的代表的状态),dynamic item被加入到UIDynamicAnimator后。你更改了dynamic item的状态。你应该使用这种方法更新dynamic item的状态
init(collectionViewLayout layout: UICollectionViewLayout) //在collection views上使用动力动画,collection view layout的坐标系作为动力行为和动力项的坐标系。动力项必须为UICollectionViewLayoutAttributes对象。可使用 setTranslatesReferenceBoundsIntoBoundaryWithInsets:设置碰撞动力界限(相对于 collection view layout的坐标系),当collection view layout发生改变时,会自己主动调用invalidateLayout、暂停、又一次開始动力
func layoutAttributesForCellAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes!//返回指定位置collection view cell的布局属性
func layoutAttributesForSupplementaryViewOfKind(kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes!//返回indexPath位置上collection view cell的指定(用kind指定)SupplementaryView的布局属性。
func layoutAttributesForDecorationViewOfKind(decorationViewKind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes!//返回indexPath位置上collection view cell的指定(用decorationViewKind指定)decorationView的布局属性。
(4)UIDynamicAnimator的常见属性
var referenceView: UIView? { get }//參照视图
var behaviors: [AnyObject] { get }//加入到物理仿真器中的全部物理仿真行为
var running: Bool { get }//是否正在进行物理仿真
unowned(unsafe) var delegate: UIDynamicAnimatorDelegate?//代理对象(能监听物理仿真器的仿真过程,比方開始和结束)
(5) UIDynamicAnimator的代理
protocol UIDynamicAnimatorDelegate : NSObjectProtocol {
optional func dynamicAnimatorWillResume(animator: UIDynamicAnimator)//UIDynamicAnimator将要启动的时候会调用
optional func dynamicAnimatorDidPause(animator: UIDynamicAnimator)//UIDynamicAnimator已经停止的时候会调用
}
Swift中的UIKit重力学的更多相关文章
- swift中类似宏定义
建一个类 如,在Contans.swift中 import UIKit let kMAIN_SIZE = UIScreen.mainScreen().bounds 在其他地方直接用 比如在 MyTab ...
- 一览Swift中的常用关键字
要学习Swift这门语言,就必须先了解Swift的关键字及对应的解释.这里就列一下在Swift中常用到的关键字. 关键字是类似于标识符的保留字符序列,除非用重音符号(`)将其括起来,否则不能用作标识符 ...
- Swift: 比较Swift中闭包传值、OC中的Block传值
一.介绍 开发者对匿名函数应该很清楚,其实它就是一个没有名字的函数或者方法,给人直观的感觉就是只能看到参数和返回值.在iOS开发中中,它又有自己的称呼,在OC中叫Block代码块,在Swift中叫闭包 ...
- swift中第三方网络请求库Alamofire的安装与使用
swift中第三方网络请求库Alamofire的安装与使用 Alamofire是swift中一个比较流行的网络请求库:https://github.com/Alamofire/Alamofire.下面 ...
- Swift基础--Swift中的分类以及在分类中扩展init方法的注意事项
Swift中的分类 1.创建一个空的swift文件 2.关键字extension,格式: extension 要扩展的类名 {} extension UIButton { } Swift中扩展init ...
- 在Swift中应用Grand Central Dispatch(上)转载自的goldenfiredo001的博客
尽管Grand Central Dispatch(GCD)已经存在一段时间了,但并非每个人都知道怎么使用它.这是情有可原的,因为并发很棘手,而且GCD本身基于C的API在 Swift世界中很刺眼. 在 ...
- Swift 中使用Nimble 库进行单元测试
Nimble 从字面上看是 敏捷,灵活 的意思.Nimble 是一个库,一个 断言库.这个库一般用于单元测试.Xcode 6 为我们集成了 XCTest 单元测试库.在正式介绍 Nimble 之前,我 ...
- 26.怎样在Swift中定义宏?
Swift 中没有宏定义,苹果建议使用let 或者 get 属性来替代宏定义值.虽然没有#define,但我们仍然可以使用 #if 并配合编译的配置来完成条件编译.下面会列出Swift项目开发中的一些 ...
- 27.怎样在Swift中声明typedef?
在OC中,我们经常会用typedef关键字来声明Block,例如: /** * 通用的空闭包类型,无参数,无返回值 */ typedef void (^GofVoidBlock)(void); 在Sw ...
随机推荐
- nodeJs入门笔记(一)
node将"HTTP服务器"这一层抽离,直接面向浏览器用户 如PHP运行之前先要配置一个功能强大而复杂的HTTP 服务器,譬如Apache.IIS 或Nginx,还需要将PHP 配 ...
- avalon.js实践 svg地图配置工具
MVVM模式,在很多复杂交互逻辑下面,有很大的优势.现在相关的框架也很多,现在项目中使用了avalon.js,选择它的原因,是兼容性的考虑,当然也要支持下国内开发大牛,至于性能方面的,没有实际测试过, ...
- echarts实现上海地域PM值(map、timeline)
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- 走进C标准库(8)——"string.h"中函数的实现相关字符串操作函数
我的strcat: char *strcat(char *dest,char *src) { char * reval = dest; while(*dest) dest++; while(*src) ...
- VHDL testbench 例子,包含向文件中写数据
LIBRARY ieee; USE ieee.std_logic_1164.ALL; use std.textio.all; use ieee.std_logic_textio.all; EN ...
- 优盘(U 盘) 采用TLC, MLC, SLC芯片 的区别 与使用寿命
最近一直在看大家在讨论sandisk,pny,金士顿等大厂都开始用tlc的芯片问题,让大家基本都不敢用U盘存数据了按照之前的擦写参数TLC 1000次MLC 10000次SL ...
- 北广传媒RTMP流媒体服务器漏洞
北广传媒移动电视(http://www.bj-mobiletv.com/)的RTMP流媒体服务器有漏洞 该漏洞可以上我们通过他们的服务器向互联网直播视频 使用任意可以发布RTMP流媒体的客户端(例如: ...
- swift3.0 构造器、析构方法(3)
构造和析构是两种特殊的方法,在对象进行初始化的时候 使用构造,在对象的释放操作中,使用析构. 构造器的定义: init (){ //代码 } init(name:String){ //代码 } 在构造 ...
- 多个target下编译的时候出错问题的解决
在工程里如果有多个target的时候,如图 那么编译的时候一定要注意Xcode右侧勾选了正确的target,否则有可能会导致一系列让你想不到的bug. ,另外,如果工程中有framework,那么一定 ...
- pywebkitgtk安装出现的问题
configure 文件里 print sys.prefix 等不能支持python3的原因 依据http://blog.csdn.net/jklfjsdj79hiofo/article/detail ...