UIKit动力学最大的特点是将现实世界动力驱动的动画引入了UIKit,比如重力,铰链连接,碰撞,悬挂等效果,即将2D物理引擎引入了UIKit
注意:UIKit动力学的引入,并不是为了替代CA或者UIView动画,在绝大多数情况下CA或者UIView动画仍然是最优方案,只有在需要引入逼真的交互设计的时候,才需要使用UIKit动力学它是作为现有交互设计和实现的一种补充
•其他2D仿真引擎:
BOX2D:C语言框架,免费
Chipmunk:C语言框架免费,其他版本收费
UIDynamic中的三个重要概念
•DynamicAnimator:动画者,为动力学元素提供物理学相关的能力及动画,同时为这些元素提供相关的上下文,是动力学元素与底层iOS物理引擎之间的中介,将Behavior对象添加到Animator即可实现动力仿真
•DynamicAnimatorItem:动力学元素,是任何遵守了UIDynamicItem协议的对象,从iOS7.0开始,UIView和UICollectionViewLayoutAttributes默认实现该协议。如果自定义的对象实现了该协议,即可通过DynamicAnimator实现物理仿真
•UIDynamicBehavior:仿真行为,是动力学行为的父类,基本的动力学行为类UIGravityBehavior、UICollisionBehavior、UIAttachmentBehavior、UISnapBehavior、UIPushBehavior以及UIDynamicItemBehavior均继承自该父类动力学动画元素(DynamicAnimator Item)协议
•只有遵守了UIDynamicItem协议的对象才可以参与到UI动力学仿真中
•从iOS7开始,UIView和UICollectionViewLayoutAttributes类默认实现了该协议
•协议定义的属性:
bounds:Dynamic
animator需要动画元素的边框时调用,只读属性,用于计算物体的边界以及质量
center:动力学元素的中心点,读写属性
transform:动力学元素的旋转角度,读写属性(需要指定Layer的形变属性)
动力学行为(Dynamic Behavior)
一个动力学行为可以为一个或者多个动力学元素赋予参与在二维动画中所具备的行为
•iOS7.0中提供的动力学行为包括:
UIGravityBehavior:重力行为
UICollisionBehavior:碰撞行为
UIAttachmentBehavior:附着行为
UISnapBehavior:吸附行为
UIPushBehavior:推行为
UIDynamicItemBehavior:动力学元素行为
•所有的UIDynamicBehavior都是可以独立作用,同时也遵守力的合成。也就是说,组合使用行为可以实现一些较复杂的效果
碰撞特性UICollisionBehavior
- ( void )collisionBehavior:( UICollisionBehavior *)behavior
beganContactForItem:( id < UIDynamicItem >)item
withBoundaryIdentifier:( id < NSCopying >)identifier a
tPoint:( CGPoint )p;
这个方法是在边界发生碰撞的时候才去执行的
UICollisionBehavior 这个和tableview的委托方法一样理解,item是碰撞的对象,identifier为对象添加定义,p为发生碰撞的位置。
如何实现碰撞这个方法呢,如下:
UICollisionBehaviorDelegate >这个委托,然后把_ground对象的委托给当前这个viewController。方法如下:
#import <UIKit/UIKit.h>
//new
@interface ViewController : UIViewController<UICollisionBehaviorDelegate>
{
UIDynamicAnimator * _animator;
UIGravityBehavior * _gravity;
UICollisionBehavior * _ground;
}
@end
- (void)viewDidLoad
{
[super viewDidLoad];
UIView * apple = [[UIView alloc] initWithFrame:CGRectMake(40,40, 40, 40)];
apple.backgroundColor = [UIColor redColor];
[self.view addSubview:apple];
_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
_gravity = [[UIGravityBehavior alloc] initWithItems:@[apple]];
[_animator addBehavior:_gravity];
_ground = [[UICollisionBehavior alloc] initWithItems:@[apple]];
_ground.translatesReferenceBoundsIntoBoundary = YES;
[_animator addBehavior:_ground];
//new
_ground.collisionDelegate = self;
}
设置_ground.collisionDelegate为试图控制器,之后当界面在发生碰撞,就可以调用一开始所说的委托方法了。
- (void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id<UIDynamicItem>)item withBoundaryIdentifier:(id<NSCopying>)identifier atPoint:(CGPoint)p{
NSLog(@"好疼,我撞在%f,%f,%@",p.x,p.y,identifier);
}