UIKit Dynamics and Motion Effects(一)

为了让用户在用你的app时有一种身临其境的感觉,UIKit Dynamics and Motion Effects可以帮你实现。

先介绍这两个tools;

UIKit Dynamics: UIKit dynamics是一个集成在UIkit中的full physics engine.用它来通过添加behaviors 比如gravity,collision等,来使用户感到interface十分的真实

可以选择interface elements元素所采纳的physics 特性,dynamics engine 照顾来做其他的事情

Motion Effects: 用Motion Effects可以创建十分cool的视差效果.


UIKit Dynamics与Motion Effects是十分强大的增强用户体验的工具,赋予digital interface生命。

getting start

打开Xcode,创建一个single View application,project name是DynamicsPlayground.创建工程以后,打开ViewController.m文件,在viewDidLoad方法下面添加以下代码:
UIView *square = [[UIView alloc[initWithFrame:CGRectMake(100,100,100,100);
square.backgroundColor = [UIColor grayColor];
[self.view addSubView:square]

以上代码添加在viewDidLoad方法里面,使得程序在load view的时候,在interface上添加了一个UIView :square

Adding gravity

在ViewController.m下,添加如下的property:
@property(strong)·UIDynamicAnimator *animator;    //declare a UIDynamicAnimator,as a physics engine
@property(strong) UIGravityBehavior *gravity;   

添加下面的代码到viewDidLoad里面:
self.animator = [[UIDynamicAnimator alloc]initWithReferenceView:self.view]; //init the animator, set reference view is self.view

self.gravity = [[UIGravityBehavior alloc]initWithItems:@[square];  // give gravity behavior add items

[self.animator addBehavior:self.gravity]

此时运行app,你会看到square慢慢的加速移动一直到脱离screen的底部边界。

UIDynamicAnimator 是UIKit physics engine,这个类追踪各种各样的添加到physics engine的行为,比如gravity,并且为这些behavior提供整个context.在初始化animator时候,传给他一个reference view,animator用这个reference view定义他自己的坐标系统,即以reference view的frame.original为坐标原点,size.width作为X轴,size.height作为Y轴

UIGravityBehavior 通过对一个或多个items施加force来模拟重力的行为,当创建一个gravity behavior时,通常要把items与gravity behavior联系起来,这些被选择的items将会受到gravity的影响

大部分behavior都允许去配置behavior property. gravity behavior可以配置他的angle和magnitude,angle决定方向,magnitude默认1.0,代表1000 points/s^2,是他的加速度,这个值越大,在相同的时间内运行的距离(points)就越大(多)。可以用0.5*g*t^2来计算下降的points,g is magnitude

setting boundaries

在运行时,square一直在向下移动,为了让square在接触到边界之后就停止运动,这就需要定义一个boundary
添加property:  UICollisionbehavior *collision;
在viewDidLoad里面初始化并把它添加到animator里面

self.collision = [[UICollisionBehavior alloc]initWithItems:@[Square]
self.collision.translatesReferenceBoundsIntoBoundary = YES ;  // 设定collision boundary is screen

[self.animator addBehavior:self.collision]

run ,会发现square将停留在screen 底部.

##################################################################

UICollisionBehavior class reference

############################
You can add multiple collision behaviors to a dynamic animator. A dynamic item can be part of any number of collision behaviors, provided those behaviors belong to the same animator. For example, you can specify a collision behavior for a set of say, blue, items and another for, say, pink items. When you add both behaviors to a dynamic animator, blue items can collide with each other and pink items can collide with each other, but a blue item and a pink item would not collide—they would ignore each other.
#########################
这段话是说,一个animator可以添加多个collision behaviors,只有在同一个collision behavior的items才会互相发生collision behavior,不同的collision behaviors的items不会发生collision behavior,在默认情况下
获取collision behavior的boundary identifier,调用property boundaryIdentifier     readonly   return array
property: collisionDelegate   对collision 的响应的掌控
Property:CollisionMode      UICollisionBehaviorModeEverything  item之间发生collision,在指定的边界也发生collision
  UICollisionBehaviorModeBoundaries  items的collision仅仅发生在指定的边界处
  UICollisionBehaviorModeItems   items的collision仅仅发生在items之间
property(readOnly) NSArray items    返回collision behaviors的items
property Bool  translatesReferenceBoundsIntoBoundary=YES   设置reference view 作为collision behavior的边界

Instance Methods:
- (void)addBoundaryWithIdentifier:(id<NSCopying>)identifier forPath:(UIBezierPath *)bezierPath

- (void)addBoundaryWithIdentifier:(id<NSCopying>)identifier fromPoint:(CGPoint)p1 toPoint:(CGPoint)p2

- (void)addItem:(id<UIDynamicItem>) item
- (UIBezierPath *)boundaryWithIdentifier:(id<NSCopying>)identifier
Returns a specified Bezier-path boundary.
- (instancetype)initWithItems:(NSArray *)items

- (void)removeAllBoundaries


- (void)removeBoundaryWithIdentifier:(id<NSCopying>)identifier

- (void)removeItem:(id<UIDynamicItem>)item
####################################################################################################
*************************************************************************************************************************************

UIBezierPath class reference

*******************************
用UIBezierPath可以定义由直的或弯的线段组成的path,path既能定义简单的shape,如椭圆,矩形,弧形,也能定义复杂的多边形
画出BezierPath所表示的几何学图像,首先要掌控the path's current point.在创建一个empty bezierPath对象时,the current point是不确定的,必须明确的指定。如果仅仅想移动current point 而不会画出line segment,用方法Move to point:.其他的方法都会画出line segments或curve segment,画的时候开始点是current point,结束在end point,end point是特别指定的,当添加画好的segment到path之后,该segment的end point将自动的变成current point

一个path可以包含任意的subpath, 用closePath可以使得open path变成close path.
moveToPoint设定先一个segment的current point

在current graphics context下,画出路径用方法stroke和fill,stroke画出path轮廓,fill来填充path所围的封闭区域
Property:  

@Property(nonatomic,readOnly) CGRect bounds;    代表包含path所有点的最小的矩形区域

@property(nonatomic,readonly) CGPoint currentPoint  代表start point,如果path是空的,currentPoint 是CGpointZero

@Property(readonly,getter = isEmpty) BooL empty   判断一个segment是否是可用的

@flatness(nonatomic) CGFloat flatness 可以精确的设定curve segment的弯曲度factor

Class methods

bezierPathWithArcCenter:radius:startAngle:endAngle:clockwise:


画一段圆弧,返回值是bezierPath,clockwise =YES,设定为顺时针

+ (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect

用在指定的矩形区域内的椭圆创建一个bezierPath
+ (UIBezierPath *)bezierPathWithRect:(CGRect)rect
  
用指定的矩形区域创建一个bezierPath

+ (UIBezierPath *)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii
在指定的矩形区域创建一个bezierPath   a rounded rectangular 

UIRectCorner

The corners of a rectangle.

enum {
   UIRectCornerTopLeft     = 1 << 0,
   UIRectCornerTopRight    = 1 << 1,
   UIRectCornerBottomLeft  = 1 << 2,
   UIRectCornerBottomRight = 1 << 3,
   UIRectCornerAllCorners  = ~0
};
typedef NSUInteger UIRectCorner;

Instance Method

- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2:

Appends a cubic Bézier curve to the receiver’s path

- (void)addLineToPoint:(CGPoint)point
Appends a straight line to the receiver’s path
- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint


- (void)appendPath:(UIBezierPath *)bezierPath
- (void)applyTransform:(CGAffineTransform)transform

CGAffineTransform

A structure for holding an affine transformation matrix.

struct CGAffineTransform {
   CGFloat a;
   CGFloat b;
   CGFloat c;
   CGFloat d;
   CGFloat tx;
   CGFloat ty;
};
typedef struct CGAffineTransform CGAffineTransform;
Fields
a

The entry at position [1,1] in the matrix.

b

The entry at position [1,2] in the matrix.

c

The entry at position [2,1] in the matrix.

d

The entry at position [2,2] in the matrix.

tx

The entry at position [3,1] in the matrix.

ty

The entry at position [3,2] in the matrix.

Discussion

In Quartz 2D, an affine transformation matrix is used to rotate, scale, translate, or skew the objects you draw in a graphics context. The CGAffineTransform type provides functions for creating, concatenating, and applying affine transformations.

In Quartz, affine transforms are represented by a 3 by 3 matrix:

A 3 by 3 matrix.

Because the third column is always (0,0,1), the CGAffineTransform data structure contains values for only the first two columns.

Conceptually, a Quartz affine transform multiplies a row vector representing each point (x,y) in your drawing by this matrix, producing a vector that represents the corresponding point (x’,y’):

A row vector multiplying a 3 by 3 matrix.

Given the 3 by 3 matrix, Quartz uses the following equations to transform a point (x, y) in one coordinate system into a resultant point (x’,y’) in another coordinate system.

Transformation equations.
********************************************************************************************************************

Handing Collisions

下面将添加一个不可移动的barrier,与square碰撞和交互
在viewDidLoad下加入:
UIView *barrier = [[UIView alloc[initWithFrame:CGRectMake(0,300,130,20)];

barrier.backgroundColor = [UIColor redColor];

[self.view addSubView:barrier];

run,将会看到barrier出现在screen的一半的地方,但是不能够与square进行交互
animator仅仅对于behaviors相联系的views才会产生影响

Making objects respond to collisions

在viewDidLoad里面用下面的代码代替self.collision的初始化
self.collision = [[UICollisionBehavior alloc]initWithItems:@[square,barrier]];
collision对象应该知道他所交互的每一个view,因此需要把barrier加入items中

run,会看到对象square和barrier可以进行collision交互,但barrier对象会移动
barrier是不可移动的,因此dynamic animator不需要检测到她的存在

Invisible boundaries and collisions

viewDidLoad里设置
self.collision = [[UICollisionBehavior alloc]initWithItems:@[square]];
然后,添加一个boundary如下:  boundary为barrier的上边界
CGPoint rightEdge = CGPointMake(barrier.frame.origin.x + barrier.frame.size.width,barrier.frame.origin.y);
[self.collision addBoundaryWithIdentifier:@1 fromPoint:barrier.origin toPoint:rightEdge];

上面添加了添加了一个让dynamic animator看得到的boundary,但barrier对dynamic animator来说是看不见的
run,可以看到square碰撞到barrier的上边界之后被弹开,然后继续向下移动

Behind the scenes of collisions

每一个dynamic behavior都有一个action property,action property提供一个block,animation的每一步都会调用action去执行action block里的代码
添加代码在viewDidLoad中:
self.collision.action  = ^{

NSLog(@"%@, %@", NSStringFromCGAffineTransform(square.transform),NSStringFromCGPoint(square.center));

}
collision 发生之后,dynamic animator用squar.transform和square.center去定位view


Collision notifications

当collision发生的时候,如果采纳了UICollisionBehaviorDelegate协议,会调用该协议的方法:
在viewDidLoad里面,在collision behavior 初始化之后,设置view controller为该collision的delegate
self.collision.collisionDelegate = self;

添加colisionBehaviorDelegate的实现方法
-(void)collisionBehavior:(UiCollisionBehavior*)behavior
beganContactForItem:(id<UIDynamicItem> item
withBoundaryIdentifier:(id<NSCopying>identifier
atPoint:(CGPoint) {
NSLog(@"Boundary conatct occured - %@",identifier);
}
当collision发生的时候,该方法被激活.

添加代码到该方法:
UIView *view = (UIView*)item;
view.backgroundColor =[UIColor yellowColor];
[UIView animateWithDuration:0.3
animations:^{
 view.backgroundColor =[UIColor grayColor];
}];

Configuring item properties   可以配置的item property包括item碰撞时的mass和弹性

在viewDidLoad的末尾添加:
UIDynamicItemBehavior *itemBehavior = [[UIDynamicItemBehavior alloc]initWithItems:@[square];
 itemBehavior.elasicity = 0.6;  //1.0 没有任何能量的损耗,
[self.animator addBehavior:itemBehavior];
还可以添加一个attach behavior

UIAttachmentBehavior *attach = [[UIAttachmentBehavior alloc]initWithItem:view attachedToItem:square];
[self.animator addBehavior:attach]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
UIDynaicItemBehavior class reference
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Property

allowsRotation  

Specifies whether rotation is allowed for the behavior’s dynamic items.

@property(readwrite, nonatomic) BOOL allowsRotation   设置item是否可以旋转

angularResistance

The angular resistance for the behavior’s dynamic items.

@property(readwrite, nonatomic)  CGFloat angularResistance   设置旋转的角度阻抗,值越大,角度衰减越大,旋转的越快,停止就越慢

density

The relative mass density of the behavior’s dynamic items.

@property(readwrite, nonatomic)  CGFloat density   设置item的密度,与item的size组合可以算出item的质量

elasticity

The amount of elasticity applied to collisions for the behavior’s dynamic items.

@property(readwrite, nonatomic)  CGFloat elasticity  1.0表示没有能量和速度的损耗

friction

The linear resistance for the behavior’s dynamic items when two slide against each other.

@property(readwrite, nonatomic)  CGFloat friction   线性阻抗 0.0 无摩擦,1.0 strong 摩擦  在平面上滑行时的阻抗

items

Returns the set of dynamic items you’ve added to the dynamic item behavior. (read-only)

@property(nonatomic, readonly, copy)  NSArray *items

resistance

The linear resistance for the behavior’s dynamic items, which reduces their linear velocity over time.

@property(readwrite, nonatomic)  CGFloat resistance

Instance Method


addAngularVelocity:forItem:

Adds a specified angular velocity to a dynamic item.

- (void)addAngularVelocity:( CGFloat) velocity forItem:(id<UIDynamicItem>) item
Parameters
velocity

The angular velocity, expressed in radians per second, that you want to add to the specified dynamic item. Default value is 0. Applying a negative value reduces the angular velocity by the specified amount.

item

The dynamic item whose angular velocity you want to increase (or decrease).

addItem:

Adds a dynamic item to the dynamic item behavior’s item array.

- (void)addItem:(id<UIDynamicItem>) item

addLinearVelocity:forItem:

Adds a specified linear velocity to a dynamic item.

- (void)addLinearVelocity:( CGPoint) velocity forItem:(id<UIDynamicItem>) item
Parameters
velocity

The linear velocity, expressed in points per second, that you want to add to the specified dynamic item. Default value is 0. Applying a negative value reduces the linear velocity by the specified amount.

item

The dynamic item whose linear velocity you want to increase (or decrease).

angularVelocityForItem:

Returns the angular velocity for a specified dynamic item.

- ( CGFloat)angularVelocityForItem:(id<UIDynamicItem>) item

initWithItems:

Initializes a dynamic item behavior with an array of dynamic items.

- (instancetype)initWithItems:( NSArray *) items

linearVelocityForItem:

Returns the linear velocity for a specified dynamic item.

- ( CGPoint)linearVelocityForItem:(id<UIDynamicItem>) item

removeItem:

Removes a specific dynamic item from the dynamic item behavior.

- (void)removeItem:(id<UIDynamicItem>) item
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

UIAttachmentBehavior class reference

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UIAttachmentBehavior指明了两个dynamic items之间的动态连接,或者是一个dynamic item和anchor point之间的连接。
默认情况下,一个item的附着点是该item的center,但可以手动改
Dynamic item 是一个遵循UIDynamicItem protocol的对象
要使Dynamic item移动,可以通过gesture或别的input

@property(readwrite, nonatomic) CGPoint anchorPoint
@property(readonly, nonatomic) UIAttachmentBehaviorType attachedBehaviorType

UIAttachmentBehaviorType

The type of an attachment behavior, indicating what a dynamic item is attached to.

typedef enum {
   UIAttachmentBehaviorTypeItems,
   UIAttachmentBehaviorTypeAnchor
} UIAttachmentBehaviorType

The amount of damping to apply to the attachment behavior.

@property(readwrite, nonatomic)  CGFloat damping
frequency

The frequency of oscillation for the attachment behavior.

@property(readwrite, nonatomic)  CGFloat frequency

items

The dynamic items connected by the attachment behavior. (read-only)

@property(nonatomic, readonly, copy)  NSArray *items

length

The distance, in points, between the two attachment points of the attachment behavior.

@property(readwrite, nonatomic)  CGFloat length

Instance Method

- (instancetype)initWithItem:(id<UIDynamicItem>)item attachedToAnchor:(CGPoint)point
Parameters
item

The dynamic item to which you are applying an attachment behavior.

point

The anchor point for the attachment behavior, relative to the coordinate system for the behavior’s associated dynamic animator. For more information, see the Overview in UIDynamicAnimator Class Reference.

initWithItem:attachedToItem:

Initializes an attachment behavior that connects the center point of a dynamic item to the center point of another dynamic item.

- (instancetype)initWithItem:(id<UIDynamicItem>) item1 attachedToItem:(id<UIDynamicItem>) item2
- ( instancetype )initWithItem:(id<UIDynamicItem>) item  offsetFromCenter:( UIOffset ) p1  attachedToAnchor:( CGPoint ) point
- (instancetype)initWithItem:(id<UIDynamicItem>)item1 offsetFromCenter:(UIOffset)p1 attachedToItem:(id<UIDynamicItem>)item2 offsetFromCenter:(UIOffset)p2
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值