UIDynamic是苹果在iOS7之后添加的一套动力学框架,简单来说就是类似与Box2d之类的物理引擎,运用它我们可以极其方便地模拟现实生活中的运动,比如重力,碰撞等等。它是通过添加行为的方式让动力学元素参与运动的。
iOS7.0中提供的动力学行为包括:
下面先来接触一下重力行为和碰撞行为:
@implementation ViewController
{
UIDynamicAnimator *_animator; //物理仿真器
UIGravityBehavior *_gravity; //重力行为
UICollisionBehavior *_collision; //碰撞行为
UIView *_view; //模拟运动的视图对象
}
1. 先初始化要模拟运动的视图对象(只有遵循了UIDynamicItem协议的对象才能参与仿真模拟,而UIView正遵循了此协议,因此所有视图控件都能参与仿真运动)
_view = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 50, 50)];
_view.backgroundColor = [UIColor blueColor];
[self.view addSubview:_view];
2. 初始化物理仿真器(相当于box2d引擎中的物理世界,凡是要参与运动的对象必须添加到此容器中)
_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
*这里是通过一个视图来初始化的,代表着整个控制器视图范围内就是一个物理仿真器
3. 添加重力行为
_gravity = [[UIGravityBehavior alloc] initWithItems:@[_view]]; //让_view对象参与重力行为运动
[_animator addBehavior:_gravity]; //所有行为必须添加到仿真器中才能生效
到这里我们就可以运行一下程序了,可以看到视图确实可以受到重力影响而下落了,不过会掉出屏幕,为了让物体保留在屏幕内我们要为物体加上碰撞行为。
4 添加碰撞行为
_collision = [[UICollisionBehavior alloc] initWithItems:@[_view]];
_collision.translatesReferenceBoundsIntoBoundary = YES; //边界检测
[_animator addBehavior:_collision];
再次运行程序,物体在下落后就不会掉出屏幕了,为了让碰撞行为更为直观,我们可以添加更多的物体参与进来,比如点击一下屏幕就产生一个物体。
添加触摸事件
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//获取点击点的坐标
CGPoint point = [[touches anyObject] locationInView:self.view];
//初始化一个视图参与运动,颜色随机
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
view.center = point;
CGFloat red = arc4random()% 200 + 55;
CGFloat green = arc4random()% 200 + 55;
CGFloat blue = arc4random()% 200 + 55;
view.backgroundColor = [UIColor colorWithRed:red/255.0 green:green/255.0 blue:blue/255.0 alpha:1.0];
[self.view addSubview:view];
//添加重力行为
[_gravity addItem:view];
//添加碰撞行为
[_collision addItem:view];
}
运行后点击屏幕是不是会发现有大量的物体掉落下来呢,很有趣吧。
不过这还没完呢,牛顿的苹果永远是往下掉的吗?能不能模拟一下重力为0或者物体飘向太空的情形呢?答案是肯定的,UIGravityBehavior重力学行为提供了一个gravityDirection的属性,这是一个CGVector类型的二维向量,可以决定重力的大小和方向,我们可以将重力改为垂直向上
_gravity.gravityDirection = CGVectorMake(0, -1);
运行一下,方块是不是都向上跑了。