【ios】UIDynamic物理模拟实现物理碰撞
一、需求:请实现下图所示的动画(物理碰撞)
二、上面引入过uidynamic 可以实现碰撞的物理效果动画,how to start ?
在工程中导入uikit,从headers 找一些uidynamic,发现了uidynamicanimator.h,uidynamicbehavior,uidynamicitembehavior
既然是要动画效果 那就应该是uidynamicanimator.h
到uidynamicanimator.h 头文件去查看注释
// when you initialize a dynamic animator with this method, you should only associates views with your behaviors. // the behaviors (and their dynamic items) that you add to the animator employ the reference view’s coordinate system. - (instancetype)initwithreferenceview:(uiview *)view ns_designated_initializer;
大概意思是使用这个初始化方法的时候,需要为你的试图关联behaviors
what’s the behaviors ? jump into defination 然而还不是很懂,uidynamicbehavior,那就查看api (注意文档中的如下描述)。
this parent class, uidynamicbehavior, is inherited by the primitive dynamic behavior classes uiattachmentbehavior, uicollisionbehavior, uigravitybehavior, uidynamicitembehavior, uipushbehavior, and uisnapbehavior.
文档中提到uidynamicbehavior的父类,那么uidynamicbehavior父类(dynamic 行为相关类)描述什么行为呢?
uiattachmentbehavior:附着行为
uicollisionbehavior:碰撞行为
uigravitybehavior:重力行为
uidynamicitembehavior:动态元素行为
uipushbehavior:推行为
uisnapbehavior:吸附行为
上述的各种行为可单独使用,也可以组合使用更复杂的动画效果。
解决方案的思路就引导到这边,也就可以实现上述需求。dynamic 行为相关类的属性可自行研究。
三、解决方案。
上述需求的解决方案(我这边用的是6sp的模拟器奥,因为在设置floor的y坐标是600)
既然是球落地效果,必然有两个模拟对象:floor,basketball
1.创建uidynamicanimator 对象
self.animator = [[uidynamicanimator alloc] initwithreferenceview:self.view];
2.刚刚在api 看到了初始化uidynamicanimator需要关联一个或者多个行为
nsarray *animatorobjects = @[self.imagev1]; // 刚刚在api 看到了初始化uidynamicanimator需要关联一个或者多个行为 self.gravitybehav = [[uigravitybehavior alloc] initwithitems:animatorobjects]; self.colision = [[uicollisionbehavior alloc] initwithitems:animatorobjects];
3.如果你想监听碰撞的状态,可以设置一下代理
self.colision.collisiondelegate = self;
4.设置碰撞边界
[self.colision addboundarywithidentifier:@"boundaryline" frompoint:cgpointmake(0, 600) topoint:cgpointmake(screenwith, 600)];
5.设置动态行为参数
// 设置动态行为参数 uidynamicitembehavior *itembehavior = [[uidynamicitembehavior alloc] initwithitems:animatorobjects]; // 设置弹性 [itembehavior setelasticity:0.5];
6.行为创建了,别忘了给animator添加上
[self.animator addbehavior:self.gravitybehav]; [self.animator addbehavior:self.colision]; [self.animator addbehavior:itembehavior];
三、下面代码只能说功能实现
ps:以下代码不符合代码书写规范
// // viewcontroller.m // dynamicanimation // // created by jeversonjee on 16/5/27. // copyright © 2016年 jeversonjee. all rights reserved. // #import "viewcontroller.h" #define screenwith [uiscreen mainscreen].bounds.size.width #define screenheight [uiscreen mainscreen].bounds.size.height @interface viewcontroller () @property (nonatomic, strong) uidynamicanimator *animator; @property (nonatomic, strong) uigravitybehavior *gravitybehav; @property (nonatomic, strong) uicollisionbehavior *colision; @property (nonatomic, strong) uiimageview *imagev1; @property (nonatomic, strong) uiimageview *imagev2; @end @implementation viewcontroller - (void)viewdidload { [super viewdidload]; // do any additional setup after loading the view, typically from a nib. [self jjcollisionbehav]; } - (void)jjcollisionbehav { // 创建碰撞需要的对象 [self jjcreateball]; [self jjcreatefloor]; // 创建uidynamicanimator 对象 self.animator = [[uidynamicanimator alloc] initwithreferenceview:self.view]; nsarray *animatorobjects = @[self.imagev1]; // 刚刚在api 看到了初始化uidynamicanimator需要关联一个或者多个行为 self.gravitybehav = [[uigravitybehavior alloc] initwithitems:animatorobjects]; self.colision = [[uicollisionbehavior alloc] initwithitems:animatorobjects]; // 这里设置代理是为了监听碰撞状态的,可以去了解一下代理方法 self.colision.collisiondelegate = self; // 设置碰撞边界 [self.colision addboundarywithidentifier:@"boundaryline" frompoint:cgpointmake(0, 600) topoint:cgpointmake(screenwith, 600)]; // 设置动态行为参数 uidynamicitembehavior *itembehavior = [[uidynamicitembehavior alloc] initwithitems:animatorobjects]; // 设置弹性 [itembehavior setelasticity:0.5]; // 创建了行为需要animator添加 [self.animator addbehavior:self.gravitybehav]; [self.animator addbehavior:self.colision]; [self.animator addbehavior:itembehavior]; } -(void)collisionbehavior:(uicollisionbehavior *)behavior endedcontactforitem:(id)item withboundaryidentifier:(id)identifier { nslog(@"collisionbehavior=%@", item); nsstring *identifierstr = [nsstring stringwithformat:@"%@", identifier]; nslog(@"s=%@", identifier); if ( [identifierstr isequaltostring:@"boundaryline"] ) { [self.imagev2 setbackgroundcolor:[uicolor graycolor]]; [uiview animatewithduration:2 animations:^(void){ [self.imagev2 setbackgroundcolor:[uicolor graycolor]]; }]; } } -(void)jjcreateball { _imagev1 = [[uiimageview alloc] initwithimage:[uiimage imagenamed:@"basketball"]]; _imagev1.frame = cgrectmake(100, 100, 60, 60); [self.view addsubview:_imagev1]; } - (void)jjcreatefloor { _imagev2 = [[uiimageview alloc] init]; [_imagev2 setbackgroundcolor:[uicolor graycolor]]; _imagev2.frame = cgrectmake(0, 600, screenwith, screenheight - 400); [self.view addsubview:_imagev2]; } -(void)didreceivememorywarning { [super didreceivememorywarning]; // dispose of any resources that can be recreated. } @end
上一篇: iOS 最新面试题(2)