UIKit Dynamics是UIKit的动力交互体系,比如重力,铰链连接,碰撞,悬挂等物理效果,它将2D物理引擎引入了人UIKit,它能使原本的动画和交互效果更加符合物理规律,当然动画效果也更逼真。
view添加重力效果
UIView *aView = [UIView new];
aView.backgroundColor = [UIColor redColor];
aView.frame = CGRectMake(self.view.frame.size.width/2, 100, 100, 100);
[self.view addSubview:aView];
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];
UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc]initWithItems:@[aView]];
[animator addBehavior:gravityBehavior];
self.animator = animator;
UIKit Dynamics基础
为了实现动力行为UI,我们必须先了解四个对象
- UIDynamicItem:用来描述一个力学物体的状态,其实就是实现了UIDynamicItem委托的对象,或者抽象为有面积有旋转的质点;
- UIDynamicBehavior:动力行为的描述,如例子中的重力行为
- UIDynamicAnimator:动力行为(UIDynamicBehavior)的容器,添加到容器内的行为将发挥作用。
- ReferenceView:力学参考对象,就是对象在哪个view中会产生响应的力学行为,例子中
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];
对象产生力学作用的区域是 self.view
场见的力学行为有这么几种
- UIAttachmentBehavior:连接行为
- UICollisionBehavior:碰撞行为
- UIGravityBehavior:重力行为
- UIPushBehavior:推力行为
- UISnapBehavior:不知道怎么翻译,实际效果类似吸引力
重力+碰撞
前面的demo中view会一直落下,变成落到地下后就停止
UIView *aView = [UIView new];
aView.backgroundColor = [UIColor redColor];
aView.frame = CGRectMake(self.view.frame.size.width/2, 100, 100, 100);
aView.transform = CGAffineTransformRotate(aView.transform, 45);
[self.view addSubview:aView];
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];
UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc]initWithItems:@[aView]];
[animator addBehavior:gravityBehavior];
UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc]initWithItems:@[aView]];
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
[animator addBehavior:collisionBehavior];
collisionBehavior.collisionDelegate =self;
self.animator = animator;
重力+附着力
UIAttachmentBehavior是连接行为,要把view钉在某一位置,就给他添加连接行为即可
UIView *aView = [UIView new];
aView.backgroundColor = [UIColor redColor];
aView.frame = CGRectMake(self.view.frame.size.width/2, 100, 100, 100);
aView.transform = CGAffineTransformRotate(aView.transform, 45);
[self.view addSubview:aView];
self.aView = aView;
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];
UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc]initWithItems:@[aView]];
[animator addBehavior:gravityBehavior];
UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc]initWithItems:@[aView]];
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
[animator addBehavior:collisionBehavior];
collisionBehavior.collisionDelegate =self;
UIPanGestureRecognizer *gest = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handleAttachmentGesture:)];
[aView addGestureRecognizer:gest];
self.animator = animator;
- (void)handleAttachmentGesture:(UIPanGestureRecognizer*)gesture{
if (gesture.state == UIGestureRecognizerStateBegan) {
CGPoint squareCenterPoint = CGPointMake(self.aView.center.x, self.aView.center.y-100);
UIAttachmentBehavior *attachmentBehavior = [[UIAttachmentBehavior alloc]initWithItem:self.aView attachedToAnchor:squareCenterPoint];
self.attachmentBehavior = attachmentBehavior;
[self.animator addBehavior:attachmentBehavior];
}else if (gesture.state==UIGestureRecognizerStateChanged){
[self.attachmentBehavior setAnchorPoint:[gesture locationInView:self.view]];
}else if (gesture.state==UIGestureRecognizerStateEnded){
[self.animator removeBehavior:self.attachmentBehavior];
}
}