UIDynamic
UIKit 动力学最大的特点是将现实世界动力驱动的动画引入了UIKit ,比如重力,铰链连接,碰撞,悬挂等效果,即将2D物理引擎引入了UIKit
- 注意:
UIKit 动力学的引入,并不是为了替代CA 或者UIView 动画,在绝大多数情况下CA 或者UIView 动画仍然是最优方案,只有在需要引入逼真的交互设计的时候,才需要使用UIKit 动力学它是作为现有交互设计和实现的一种补充 - 其他
2D 仿真引擎:BOX2D C语言框架免费;Chipmunk C语言框架免费,其他版本收费
UIDynamic三个重要的概念
-
DynamicAnimator :动画者,为动力学元素提供物理学相关的能力及动画,同时为这些元素提供相关的上下文,是动力学元素与底层os物理引擎之间的中介,将Behavior 对象添加到 Animator 即可实现动力仿真 -
DynamicAnimatorItem :动力学元素,是任何遵守了 UIDynamicItem 协议的对象,从IOS7.0 开始,UIView 和UICollectionViewLayoutAttributes 默认实现该协议。如果自定义的对象实现了该协议,即可通过DynamicAnimator 实现物理仿真 -
UIDynamicBehavior :仿真行为,是动力学行为的父类,基本的动力学行为类 UIGravityBehavior :重力行为 UICollisionBehavior : 碰撞行为 UlAttachmentBehavior :吸附行为 UISnapBehavior :甩行为 UIPushBehavior :推动行为 UIDynamicItemBehavior :动力学元素自身属性
重力
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.redView]];
[animator addBehavior:gravity];
设置角度
gravity.angle = M_PI;
设置方向 按照x,y轴
gravity.gravityDirection = CGVectorMake(1, 1);
重力的量级
gravity.magnitude = 10;
碰撞
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.redView]];
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.redView]];
collision.translatesReferenceBoundsIntoBoundary = YES;
[animator addBehavior:gravity];
[animator addBehavior:collision];
碰撞模式选择
typedef NS_OPTIONS(NSUInteger, UICollisionBehaviorMode) {
UICollisionBehaviorModeItems = 1 << 0,
UICollisionBehaviorModeBoundaries = 1 << 1,
UICollisionBehaviorModeEverything = NSUIntegerMax
} API_AVAILABLE(ios(7.0));
碰撞模式,默认是UICollisionBehaviorModeEverything
collision.collisionMode = UICollisionBehaviorModeEverything;
添加边界
[collision addBoundaryWithIdentifier:@"key" fromPoint:CGPointMake(0, 200) toPoint:CGPointMake(200, 250)];
为view添加固定的边界
UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.blueView.frame];
[collision addBoundaryWithIdentifier:@"key" forPath:path];
实时监听函数
collision.action = ^{
};
@protocol UICollisionBehaviorDelegate <NSObject>
@optional
- (void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2 atPoint:(CGPoint)p;
- (void)collisionBehavior:(UICollisionBehavior *)behavior endedContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2;
- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(nullable id <NSCopying>)identifier atPoint:(CGPoint)p;
- (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(nullable id <NSCopying>)identifier;
@end
collision.collisiondelegate = self;
- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(nullable id <NSCopying>)identifier atPoint:(CGPoint)p{
NSString *str = (NSString *)identifier;
if([str isEquelToString:@"key"]){
self.redView.backgroundColor = [UIColor redColor];
}
}
甩行为
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];
UITouch *touch = touches.anyObject;
CGPoint p = [touch locationInView:touch.view];
UISnapBehavior *snap = [[UISnapBehavior alloc] initWithItem:self.redView snapToPoint:p];
[animator addBehavior:snap];
减速程度
snap.damping = 0;
吸附行为
UITouch *touch = touches.anyObject;
CGPoint p = [touch locationInView:touch.view];
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];
UIAttachmentBehavior *attach = [[UIAttachmentBehavior alloc]initWithItem:self.redView attachedToAnchor:p];
[animator addBehavior:attach];
需要写在touchMove里面,附着点
attach.anchorPoint = p;
吸附杠长度
attach.length = 100;
设置弹性吸附
attach.damping = 0.5;
attach.frequency = 10;
推行为
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];
UIPushBehavior *push = [[UIPushBehavior alloc]initWithItems:@[self.redView] mode:UIPushBehaviorModeContinuous];
push.magnitude = 1;
push.angle = M_PI;
push.pushDirection = CGVectorMake(100, 100);
[animator addBehavior:push];
动力学元素自身属性
@property (readwrite, nonatomic) CGFloat elasticity;
@property (readwrite, nonatomic) CGFloat friction;
@property (readwrite, nonatomic) CGFloat density;
@property (readwrite, nonatomic) CGFloat resistance;
@property (readwrite, nonatomic) CGFloat angularResistance;
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];
UIPushBehavior *push = [[UIPushBehavior alloc]initWithItems:@[self.redView] mode:UIPushBehaviorModeContinuous];
UIDynamicItemBehavior *itemBehavior = [[UIDynamicItemBehavior alloc]initWithItems:@[self.redView]];
itemBehavior.friction = 0.5;
itemBehavior.elasticity = 1;
[animator addBehavior:push];
[animator addBehavior:itemBehavior];
|