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 second2.
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已经停止的时候会调用

}

时间: 2024-12-20 06:57:18

Swift中的UIKit重力学的相关文章

[爱上Swift] day8:讲解Swift中的UIKit重力学(一)

转自:http://www.itjhwd.com/swift-uikitzlx/ 重力学这个名词不论在哪个行业领域听起来似乎都很高大上.那么在Swift中的重力学是什么呢?那就是将我们移动端屏幕上毫无生命力的东西也置于万有引力中,使它们能够展现出好像真的由于引力而向下坠落以及碰到物体后自然的弹开的效果. 要想做到这一点,我们得需要两个利器:UIKit Dynamics和Motion Effects. UIKit Dynamics是UIKit中一套完整的物理引擎.它可以让我们在程序中对界面元素添加

swift中类似宏定义

建一个类 如,在Contans.swift中 import UIKit let kMAIN_SIZE = UIScreen.mainScreen().bounds 在其他地方直接用 比如在 MyTabbarViewController.swift中 var bgView = UIView(frame:CGRectMake(0, 0, kMAIN_SIZE.width, kMAIN_SIZE.height - 20 - 44)); swift中类似宏定义,布布扣,bubuko.com

如何在Swift中创建自定义控件

更新通知:这篇引导教程由Mikael Konutgan使用iOS 8和Swift语言重新制作,在Xcode6和7上测试通过.原始教程是由Colin Eberhardt团队制作的. 用户界面控件是许多应用的重要组成部分.使用这些控件,可以让用户查看应用的内容或与他们的应用进行交互.苹果提供了一个控件集,像UITextField, UIButton 和 UISwitch.灵活使用这些工具箱中已经存在的控件,可以让你创建各种各样的用户界面. 但是,有的时候你可能需要做一些与众不同的事情:库中的控件已经

swift中代理的使用

下面以自定义的UITableViewCell的代理为例,记录一下swift中代理的使用 controller中的代码如 1 // 2 // ViewController.swift 3 // simpleDemo 4 // 5 // Created by liubo on 16/7/25. 6 // Copyright © 2016年 liubo. All rights reserved. 7 // 8 9 import UIKit 10 11 class ViewController: UIV

swift中变量的几种类型

swift中变量分为 optional,non-optional 以及 implicitly unwrapped optional 这几种类型 var nullableProperty : AnyObject? // optional var nonNullProperty : AnyObject // non-optional var unannotatedProperty : AnyObject! // implicitly unwrapped optional 其中,optional (如

swift中tableview的使用和注意事项

今天使用swift写了个简单的tableView,语法和用法上跟oc没多大的区别.但是还是有一些细节的地方需要注意一下的. 先上代码 import UIKit class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource { var _tableView:UITableView? override func viewDidLoad() { super.viewDidLoad() _tableVie

Swift中KVO(监听)的使用方法及注意事项

---恢复内容开始--- 相信研究swift语言的开发者都多多少少了解或者精通Objective—C语言,熟练掌握Objective—C语言的开发者,在学习swift语言的过程中,是比较快速,而又轻松的.本人就是一位熟练掌握OC语言,后开始研究的swift.在学习swift语言的过程中,笔者建议有OC基础的开发者,在写swift的代码过程中,再写一下OC中的代码,二者相互比较,相信你能找到快速学会swift语言的方法.资深,有耐心和有天赋的开发者,相信能在一周左右,能够运用swift开发项目.其

swift中实例方法和类方法的书写格式

其实swift中的实例方法和类方法的区分很简单,喜欢看源代码的,肯定一眼就看懂了.类方法的定义就是在实例方法前面加一个class修饰即可.还是附上一篇实例代码吧. ViewController.swift中 // // ViewController.swift // 类方法和实例方法的定义 // // Created by mac on 16/2/6. // Copyright © 2016年 ZY. All rights reserved. // import UIKit class View

swift中通知的使用方法

其实swift语言和OC语言,在本质上都是一样,其里面的方法之类的也基本相同.通知的使用方法也是一样,只是代码的书写格式发生了改变而已.下面我通过一个简单的小需求,也讲一讲通知,用swift中的闭包,也能完成此功能. 使用通知需要注意事项: 1,先确保接收中心存在,在设置通知中心. 2,最后一定要移除通知中心. 3,通知也是可以传值的,放在userInfo里面. 具体界面效果,我在这里就不截图了,希望各位开发者,自己写一遍,然后运行. ViewController // //  ViewCont