UIDynamic
UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象如:重力、弹性碰撞等现象
任何遵守了UIDynamicItem协议的对象
UIView默认已经遵守了UIDynamicItem协议,因此任何UI控件都能做物理仿真
UICollectionViewLayoutAttributes类默认也遵守UIDynamicItem协议
接下来我们试着用代码来实现UI控件的仿真行为,做一些有趣的实验,说一说具体实现的步骤,做的东西比较简单,希望对大家有所帮助.
1首先我们现在storyboard添加两个UIView控件,在控制器中拖线进行关联,便于访问两个UIView对象
@property (weak, nonatomic) IBOutlet UIView *testViewOne;
@property (weak, nonatomic) IBOutlet UIView *testViewTwo;
2.要给两个控件添加仿真行为首先得创建一个物理仿真器对象
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
self.animator = animator;
3.接下来创建想要的物理仿真行为(如重力、碰撞、附着等)
基本步骤:
1.创建仿真行为对象(创建的时候,会指定仿真行为添加给那些元素/控件)
2.设置仿真对象的参数(或是属性)
3.将物理仿真行为添加到物理仿真器中
//创建重力仿真行为
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.testViewOne, self.testViewTwo]];
//设置重力行为的属性(参数)
gravity.gravityDirection = CGVectorMake(0, 1); // 方向
gravity.magnitude = 1; //加速度
//创建碰撞
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.testViewOne, self.testViewTwo]];
//设置碰撞边界
collision.translatesReferenceBoundsIntoBoundary = YES;
/**添加自定义的边界**/
//创建路径
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(150, 350, 300, 140)];
//添加边界
[collision addBoundaryWithIdentifier:@"customBoundary" forPath:path];
//检测碰转要设置代理
collision.collisionDelegate = self;
//设置碰转的模式
//UICollisionBehaviorModeItems 只和物体碰撞
//UICollisionBehaviorModeBoundaries 只和边界碰撞
//UICollisionBehaviorModeEverything 物体碰撞和边界碰撞
collision.collisionMode = UICollisionBehaviorModeEverything;
当然为了达到良好的仿真行为效果,也可设置元素/控件的自身的参数设置
//设置视图的辅助行为(本身参数 弹性系数 阻力等)
// elasticity; // Usually between 0 (inelastic) and 1 (collide elastically) 弹性系数
// friction; // 0 being no friction between objects slide along each other 摩擦力
// density; // 1 by default 密度
// resistance; // 0: no velocity damping 阻力
// angularResistance; // 0: no angular velocity damping
// allowsRotation; // force an item to never rotate 是否允许旋转
UIDynamicItemBehavior *item = [[UIDynamicItemBehavior alloc] initWithItems:@[self.testViewOne, self.testViewTwo]];
item.elasticity = 0.9;
item.friction = 0;
item.density = 1;
item.resistance = 0.3;
item.angularResistance = 0.6;
//将仿真行为添加到仿真器中
[animator addBehavior:gravity];
[animator addBehavior:collision];
[animator addBehavior:item];
当然,物理仿真中还提供了代理方法方便开发者在执行仿真动画的同时做一些其他的操作
//物体和物体开始碰撞
- (void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id)item1 withItem:(id)item2 atPoint:(CGPoint)p {
UIView *viewOne = (UIView *)item1;
UIView *viewTwo = (UIView *)item2;
viewOne.backgroundColor = [self randomColor];
viewTwo.backgroundColor = [self randomColor];
self.view.backgroundColor = [self randomColor];
}
//物体和物体结束碰撞
- (void)collisionBehavior:(UICollisionBehavior *)behavior endedContactForItem:(id)item1 withItem:(id)item2 {
//自己想要的操作
}
//物体和边界开始碰撞
- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id)item withBoundaryIdentifier:(nullable id)identifier atPoint:(CGPoint)p {
UIView *view = (UIView *)item;
view.backgroundColor = [self randomColor];
self.view.backgroundColor = [self randomColor];
}
//物体和边界结束碰撞
- (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id)item withBoundaryIdentifier:(nullable id)identifier {
//自己想要的操作
}
感兴趣的朋友可以试着做一些有趣的效果,物理仿真可下载源码