iOS开发UIKit动力学——UIKit Dynamics
2015-07-01 17:52
441 查看
UIKit Dynamics其实就是UIKit对一些物理学行为仿真的封装。使用UIKit动力学对常用的iOS动画CoreAnimation、UIView animations进行补充。
我们应该了解的基本概念:
UIDynamicItem:用来描述一个力学物体的状态,其实就是实现了UIDynamicItem委托的对象。从iOS 7.0开始,UIView和UICollectionViewLayoutAttributes默认实现该协议。如果自定义的对象实现了该协议,即可通过Dynamic
Animator实现物理仿真。
UIDynamicBehavior:动力行为的描述,用来指定UIDynamicItem应该如何运动,即定义适用的物理规则。一般我们使用这个类的子类对象来对一组UIDynamicItem应该遵守的行为规则进行描述。
UIDynamicAnimator:动画的播放者,动力行为(UIDynamicBehavior)的容器,添加到容器内的行为将发挥作用。
ReferenceView:等同于力学参考系,只有当想要添加力学行为的UIView是ReferenceView的子view时,动力UI才发生作用。
UIKit动力学行为包括:UIGravityBehavior(重力),UICollisionBehavior(碰撞),UIAttachmentBehavior(吸附),UISnapBehavior(捕捉),UIPushBehavior(推动)以及辅助行为UIDynamicItemBehavior。所有的UIDynamicBehavior都是可以独立作用,同时也遵守力的合成。也就是说,组合使用行为可以实现一些较复杂的效果。
1. UIDynamicItemBehavior:辅助的行为,用来设置运动学元素参与物理仿真过程中的参数,如:弹性系数、摩擦系数、密度、阻力、角阻力以及是否允许旋转等。
elasticity(弹性系数):决定了碰撞的弹性程度,比如碰撞时物体的弹性
friction(摩擦系数) :决定了沿接触面滑动时的摩擦力大小
density(密度): 跟size结合使用,计算物体的总质量。质量越大,物体加速或减速就越困难
resistance(阻力):决定线性移动的阻力大小,与摩擦系数不同,摩擦系数只作用于滑动运动
angularResistance(角阻力) :决定旋转运动时的阻力大小
allowsRotation(允许旋转):这个属性很有意思,它在真实的物理世界没有对应的模型。设置这个属性为
NO 物体就完全不会转动,而无论施加多大的转动力
2. UIGravityBehavior:重力行为
3. UICollisionBehavior:碰撞行为
3. UIAttachmentBehavior:附着行为
1.附着行为描述一个视图与一个锚点或者另一个视图相连接的情况
2.附着行为描述的是两点之间的连接情况,可以模拟刚性或者弹性连接
3.在多个物体间设定多个UIAttachmentBehavior,可以模拟多物体连接
4. 属性:
attachedBehaviorType:连接类型(连接到锚点或视图)
items:连接视图数组
anchorPoint:连接锚点
length:距离连接锚点的距离
只要设置了以下两个属性,即为弹性连接
damping:振幅大小
frequency:振动频率
4. UISnapBehavior:捕捉行为
1.捕捉行为可以将视图通过动画吸附到某个点上
2. 初始化设定一下UISnapBehavior的initWithItem:snapToPoint:即可
3. 属性:
damping:振幅大小,默认为0.5f
5. 推动行为:UIPushBehavior
1. 推动行为可以为一个视图施加一个作用力,该力可以是持续的,也可以是一次性的
2. 可以设置力的大小,方向和作用点等信息
3. 属性:
•mode:推动类型(一次性或是持续推)
•active:是否激活,如果是一次性推,需要激活
•angle:推动角度
•magnitude:推动力量
初始化的时候有两种模式:UIPushBehaviorModeContinuous(这个模型可以忽略)
总结:
1. 实例化UIKit Dynamics所有相关的类都是通过allco,init创建的,没有提供类方法。
2. 使用UIKit Dynamics的步凑:
1. 实例化动画的仿真者UIDynamicAnimator,并设置参考视图用于物理仿真。参考视图表示要仿真的范围。
注意:UIDynamicAnimator类的实例需作为成员变量,防止方法执行完后被销毁,每个对象拥有一个UIDynamicAnimator管理其动力学行为。
2. 实例化要仿真的行为,并指定哪些对象遵守该行为。
3. 将要仿真的行为添加至仿真者UIDynamicAnimator,仿真立即开始。
参考文章:
http://blog.csdn.net/gandam19/article/details/19498315 http://www.th7.cn/Program/IOS/201312/166139.shtml
我们应该了解的基本概念:
UIDynamicItem:用来描述一个力学物体的状态,其实就是实现了UIDynamicItem委托的对象。从iOS 7.0开始,UIView和UICollectionViewLayoutAttributes默认实现该协议。如果自定义的对象实现了该协议,即可通过Dynamic
Animator实现物理仿真。
UIDynamicBehavior:动力行为的描述,用来指定UIDynamicItem应该如何运动,即定义适用的物理规则。一般我们使用这个类的子类对象来对一组UIDynamicItem应该遵守的行为规则进行描述。
UIDynamicAnimator:动画的播放者,动力行为(UIDynamicBehavior)的容器,添加到容器内的行为将发挥作用。
ReferenceView:等同于力学参考系,只有当想要添加力学行为的UIView是ReferenceView的子view时,动力UI才发生作用。
UIKit动力学行为包括:UIGravityBehavior(重力),UICollisionBehavior(碰撞),UIAttachmentBehavior(吸附),UISnapBehavior(捕捉),UIPushBehavior(推动)以及辅助行为UIDynamicItemBehavior。所有的UIDynamicBehavior都是可以独立作用,同时也遵守力的合成。也就是说,组合使用行为可以实现一些较复杂的效果。
1. UIDynamicItemBehavior:辅助的行为,用来设置运动学元素参与物理仿真过程中的参数,如:弹性系数、摩擦系数、密度、阻力、角阻力以及是否允许旋转等。
elasticity(弹性系数):决定了碰撞的弹性程度,比如碰撞时物体的弹性
friction(摩擦系数) :决定了沿接触面滑动时的摩擦力大小
density(密度): 跟size结合使用,计算物体的总质量。质量越大,物体加速或减速就越困难
resistance(阻力):决定线性移动的阻力大小,与摩擦系数不同,摩擦系数只作用于滑动运动
angularResistance(角阻力) :决定旋转运动时的阻力大小
allowsRotation(允许旋转):这个属性很有意思,它在真实的物理世界没有对应的模型。设置这个属性为
NO 物体就完全不会转动,而无论施加多大的转动力
2. UIGravityBehavior:重力行为
// 实例化重力行为 UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] initWithItems:self.imageViews]; // 将重力行为添加至仿真者 [self.animator addBehavior:gravityBehavior];
3. UICollisionBehavior:碰撞行为
// 移除所有动力学行为 [self.animator removeAllBehaviors]; // 添加重力行为 UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] initWithItems:self.imageViews]; [self.animator addBehavior:gravityBehavior]; // 初始化碰撞行为 UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:self.imageViews]; // collisionBehavior.translatesReferenceBoundsIntoBoundary = YES; /* 设置碰撞模式 UICollisionBehaviorModeItems 与其他对象碰撞 UICollisionBehaviorModeBoundaries 与设置的边框碰撞 UICollisionBehaviorModeEverything 上边两种情况都碰撞 */ collisionBehavior.collisionMode = UICollisionBehaviorModeEverything; // 设置碰撞行为代理 collisionBehavior.collisionDelegate = self; [self.animator addBehavior:collisionBehavior]; // 添加附属行为 UIDynamicItemBehavior *itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:self.imageViews]; // 弹力系数 0 ~ 1 itemBehavior.elasticity = 0.8; [self.animator addBehavior:itemBehavior];
3. UIAttachmentBehavior:附着行为
1.附着行为描述一个视图与一个锚点或者另一个视图相连接的情况
2.附着行为描述的是两点之间的连接情况,可以模拟刚性或者弹性连接
3.在多个物体间设定多个UIAttachmentBehavior,可以模拟多物体连接
4. 属性:
attachedBehaviorType:连接类型(连接到锚点或视图)
items:连接视图数组
anchorPoint:连接锚点
length:距离连接锚点的距离
只要设置了以下两个属性,即为弹性连接
damping:振幅大小
frequency:振动频率
- (void)performAttachmentBehavior
{
if (self.animator == nil) {
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
} else {
[self.animator removeAllBehaviors];
}
for (int i = 0; i < self.imageViews.count; i++) {
CGRect frame = CGRectMake(20 + i * 60, 400, 50, 50);
[self.imageViews[i] setFrame:frame];
}
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(attachmentBechaviorPanGesture:)];
[self.view addGestureRecognizer:panGestureRecognizer];
for (int i = 0; i < self.imageViews.count - 1; i++) {
UIAttachmentBehavior *attachmentBehavior = [[UIAttachmentBehavior alloc] initWithItem:self.imageViews[i] attachedToItem:self.imageViews[i + 1]];
attachmentBehavior.frequency = 0.8;
attachmentBehavior.damping = 0.5;
attachmentBehavior.length = 50;
[self.animator addBehavior:attachmentBehavior];
}
}
- (void)attachmentBechaviorPanGesture:(UIPanGestureRecognizer *)gesture
{
CGPoint location = [gesture locationInView:self.view];
if (gesture.state == UIGestureRecognizerStateBegan) {
// [(UIImageView *) self.imageViews[0] setCenter:loction];
[self initDragBehaviourWithAnchorPosition:location];
[self.animator addBehavior:self.dragBehavior];
}else if (gesture.state == UIGestureRecognizerStateChanged) {
[self.dragBehavior setAnchorPoint:location];
} else if (gesture.state == UIGestureRecognizerStateEnded){
// 移除所有动力学行为 [self.animator removeAllBehaviors]; // 添加重力行为 UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] initWithItems:self.imageViews]; [self.animator addBehavior:gravityBehavior]; // 初始化碰撞行为 UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:self.imageViews]; // collisionBehavior.translatesReferenceBoundsIntoBoundary = YES; /* 设置碰撞模式 UICollisionBehaviorModeItems 与其他对象碰撞 UICollisionBehaviorModeBoundaries 与设置的边框碰撞 UICollisionBehaviorModeEverything 上边两种情况都碰撞 */ collisionBehavior.collisionMode = UICollisionBehaviorModeEverything; // 设置碰撞行为代理 collisionBehavior.collisionDelegate = self; [self.animator addBehavior:collisionBehavior]; // 添加附属行为 UIDynamicItemBehavior *itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:self.imageViews]; // 弹力系数 0 ~ 1 itemBehavior.elasticity = 0.8; [self.animator addBehavior:itemBehavior];
}
}
- (void)initDragBehaviourWithAnchorPosition:(CGPoint)anchorPosition {
UIView *obj = self.imageViews[0];
self.dragBehavior = [[UIAttachmentBehavior alloc] initWithItem:obj attachedToAnchor:anchorPosition];
double length = [self getDistanceBetweenAnchor:anchorPosition andBallView:obj];
[self.dragBehavior setLength:((CGFloat) length < 20) ? (CGFloat) length : 20];
}
- (double)getDistanceBetweenAnchor:(CGPoint)anchor andBallView:(UIView *)ballView {
return sqrt(pow((anchor.x - ballView.center.x), 2.0) + pow((anchor.y - ballView.center.y), 2.0));
}
4. UISnapBehavior:捕捉行为
1.捕捉行为可以将视图通过动画吸附到某个点上
2. 初始化设定一下UISnapBehavior的initWithItem:snapToPoint:即可
3. 属性:
damping:振幅大小,默认为0.5f
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[view]]; [self.animator addBehavior:gravityBehavior]; UISnapBehavior *snapBehavior = [[UISnapBehavior alloc] initWithItem:view snapToPoint:self.view.center]; snapBehavior.damping = 0.2; [self.animator addBehavior:snapBehavior];
5. 推动行为:UIPushBehavior
1. 推动行为可以为一个视图施加一个作用力,该力可以是持续的,也可以是一次性的
2. 可以设置力的大小,方向和作用点等信息
3. 属性:
•mode:推动类型(一次性或是持续推)
•active:是否激活,如果是一次性推,需要激活
•angle:推动角度
•magnitude:推动力量
初始化的时候有两种模式:UIPushBehaviorModeContinuous(这个模型可以忽略)
- (void)performPushBehavior { if (self.centerview == nil) { self.centerview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 150)]; self.centerview.backgroundColor = [UIColor greenColor]; self.centerview.center = self.view.center; [self.view addSubview:self.centerview]; } UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureAction:)]; [self.view addGestureRecognizer:panGesture]; } - (void)panGestureAction:(UIPanGestureRecognizer *) recongnizer { CGPoint firsPoint = CGPointZero; CGPoint endPoint = CGPointZero; CGPoint location = [recongnizer locationInView:self.view]; if (recongnizer.state == UIGestureRecognizerStateBegan) { firsPoint = location; } else if (recongnizer.state == UIGestureRecognizerStateEnded) { endPoint = location;; UIPushBehavior *pushBehavior = [[UIPushBehavior alloc] initWithItems:@[self.centerview] mode:UIPushBehaviorModeInstantaneous ]; pushBehavior.active = YES; CGFloat distance = sqrtf(powf((endPoint.x - firsPoint.x), 2) + powf(endPoint.y - firsPoint.y, 2)); CGFloat angle = atan2f(endPoint.y - firsPoint.y, endPoint.x - firsPoint.x); pushBehavior.angle = angle; pushBehavior.magnitude = distance/100; // pushBehavior.pushDirection = CGVectorMake(1, 0); // [pushBehavior setPushDirection:CGVectorMake([recongnizer velocityInView:self.view].x /100.f, 0)]; [self.animator addBehavior:pushBehavior]; } else if (recongnizer.state == UIGestureRecognizerStateEnded) { } }
总结:
1. 实例化UIKit Dynamics所有相关的类都是通过allco,init创建的,没有提供类方法。
2. 使用UIKit Dynamics的步凑:
1. 实例化动画的仿真者UIDynamicAnimator,并设置参考视图用于物理仿真。参考视图表示要仿真的范围。
注意:UIDynamicAnimator类的实例需作为成员变量,防止方法执行完后被销毁,每个对象拥有一个UIDynamicAnimator管理其动力学行为。
2. 实例化要仿真的行为,并指定哪些对象遵守该行为。
3. 将要仿真的行为添加至仿真者UIDynamicAnimator,仿真立即开始。
参考文章:
http://blog.csdn.net/gandam19/article/details/19498315 http://www.th7.cn/Program/IOS/201312/166139.shtml
相关文章推荐
- 将View设置为Opaque
- uil的简单常用操作
- UIDatePicker获取时间
- ios-UITextField详解
- NGUI DrawCall数量优化( 记录备忘 )
- iOS UI之删除导航栏左侧按钮
- 自定义UISlider的样式和滑块
- nyoj 483 Nightmare 【BFS + priority_queue】
- HDU 2767-Proving Equivalences(强联通+缩点)
- UIImagePickerController 状态栏颜色改变,自定义返回按钮
- 如何运用UIControl自定义iOS中的控件
- UI控件
- MQTT的学习研究(六) MQTT moquette 的 Blocking API 订阅消息客户端使用
- MQTT的学习研究(五) MQTT moquette 的 Blocking API 发布消息服务端使用
- MQTT的学习研究(四)moquette-mqtt 的使用之mqtt Blocking API客户端订阅并接收主题信息
- MQTT的学习研究(三)moquette-mqtt 的使用之mqtt服务发布主题信息
- MQTT的学习研究(二)moquette-mqtt 的使用之mqtt broker的启动
- UI效果
- Android自动化测试(UiAutomator)简要介绍
- ArduinoYun教程之配置Arduino Yun环境