首页 / IOS / IOS-UIDynamic
IOS-UIDynamic
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了IOS-UIDynamic,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含13032字,纯文字阅读大概需要19分钟。
内容图文
![IOS-UIDynamic](/upload/InfoBanner/zyjiaocheng/1192/1d6fa2c414b649d9bd7c60d75c2e4e4b.jpg)
1 // 2 // ViewController.m 3 // IOS_0306_UIDynamic 4 // 5 // Created by ma c on 16/3/6. 6 // Copyright ? 2016年 博文科技. All rights reserved. 7 // 8 9 #import " ViewController.h " 10 11 @interface ViewController () 12 13 @property (weak, nonatomic) IBOutlet UIView *redView; 14///物理仿真器 15 @property (nonatomic, strong) UIDynamicAnimator *dynamic; 16 17 18@end 19 20@implementation ViewController 21 22/* 23 一、简介 24 1.什么是UIDynamic 25 UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架 26 可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象 27 重力、弹性碰撞等现象 28 29 2.物理引擎的价值 30 广泛用于游戏开发,经典成功案例是“愤怒的小鸟” 31 让开发人员可以在远离物理学公式的情况下,实现炫酷的物理仿真效果 32 提高了游戏开发效率,产生更多优秀好玩的物理仿真游戏 33 34 3.知名的2D物理引擎 35 Box2d 36 Chipmunk 37 38 39 二、使用步骤 40 要想使用UIDynamic来实现物理仿真效果,大致的步骤如下 41 1.创建一个物理仿真器(顺便设置仿真范围) 42 43 2.创建相应的物理仿真行为(顺便添加物理仿真元素) 44 45 3.将物理仿真行为添加到物理仿真器中 ? 开始仿真 46 47 48 三、三大概念 49 1.物理仿真元素(Dynamic Item) 50 谁要进行物理仿真? 51 52 2.物理仿真行为(Dynamic Behavior) 53 执行怎样的物理仿真效果?怎样的动画效果? 54 55 3.物理仿真器(Dynamic Animator) 56 让物理仿真元素执行具体的物理仿真行为 57 58 59 四、物理仿真元素 60 1.注意 61 不是任何对象都能做物理仿真元素 62 不是任何对象都能进行物理仿真 63 64 2.哪些对象才能做物理仿真元素 65 任何遵守了UIDynamicItem协议的对象 66 UIView默认已经遵守了UIDynamicItem协议,因此任何UI控件都能做物理仿真 67 UICollectionViewLayoutAttributes类默认也遵守UIDynamicItem协议 68 69 70五、物理仿真行为 71 1.UIDynamic提供了以下几种物理仿真行为 72 UIGravityBehavior:重力行为 73 UICollisionBehavior:碰撞行为 74 UISnapBehavior:捕捉行为 75 UIPushBehavior:推动行为 76 UIAttachmentBehavior:附着行为 77 UIDynamicItemBehavior:动力元素行为 78 79 2.物理仿真行为须知 80 上述所有物理仿真行为都继承自UIDynamicBehavior 81 所有的UIDynamicBehavior都可以独立进行 82 组合使用多种行为时,可以实现一些比较复杂的效果 83 84 85 六、物理仿真器 86 1.物理仿真器须知 87 它可以让物理仿真元素执行物理仿真行为 88 它是UIDynamicAnimator类型的对象 89 90 2.UIDynamicAnimator的初始化 91 - (instancetype)initWithReferenceView:(UIView *)view; 92 view参数:是一个参照视图,表示物理仿真的范围 93 94 3.UIDynamicAnimator的常见方法 95 - (void)addBehavior:(UIDynamicBehavior *)behavior; 96 添加1个物理仿真行为 97 98 - (void)removeBehavior:(UIDynamicBehavior *)behavior; 99 移除1个物理仿真行为 100101 - (void)removeAllBehaviors; 102 移除之前添加过的所有物理仿真行为 103104 4.UIDynamicAnimator的常见属性 105 @property (nonatomic, readonly) UIView* referenceView; 106 参照视图 107108 @property (nonatomic, readonly, copy) NSArray* behaviors; 109 添加到物理仿真器中的所有物理仿真行为 110111 @property (nonatomic, readonly, getter = isRunning) BOOL running; 112 是否正在进行物理仿真 113114 @property (nonatomic, assign) id <UIDynamicAnimatorDelegate> delegate; 115 代理对象(能监听物理仿真器的仿真过程,比如开始和结束) 116117118 七.重力行为(UIGravityAnimator) 119 1.简介 120 给定重力方向、加速度,让物体朝着重力方向掉落 121122 2.UIGravityBehavior的初始化 123 - (instancetype)initWithItems:(NSArray *)items; 124 item参数 :里面存放着物理仿真元素 125126 3.UIGravityBehavior常见方法 127 - (void)addItem:(id <UIDynamicItem>)item; 128 添加1个物理仿真元素 129130 - (void)removeItem:(id <UIDynamicItem>)item; 131 移除1个物理仿真元素 132133 4.UIGravityBehavior常见属性 134 @property (nonatomic, readonly, copy) NSArray* items; 135 添加到重力行为中的所有物理仿真元素 136137 @property (readwrite, nonatomic) CGVector gravityDirection; 138 重力方向(是一个二维向量) 139140 @property (readwrite, nonatomic) CGFloat angle; 141 重力方向(是一个角度,以x轴正方向为0°,顺时针正数,逆时针负数) 142143 @property (readwrite, nonatomic) CGFloat magnitude; 144 量级(用来控制加速度,1.0代表加速度是1000 points /second2) 145146147 八、碰撞行为(UICollisionBehavior) 148 1.简介 149 可以让物体之间实现碰撞效果 150 可以通过添加边界(boundary),让物理碰撞局限在某个空间中 151152 2.UICollisionBehavior边界相关的方法 153 - (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier forPath:(UIBezierPath*)bezierPath; 154 - (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier fromPoint:(CGPoint)p1 toPoint:(CGPoint)p2; 155 - (UIBezierPath*)boundaryWithIdentifier:(id <NSCopying>)identifier; 156 - (void)removeBoundaryWithIdentifier:(id <NSCopying>)identifier; 157 @property (nonatomic, readonly, copy) NSArray* boundaryIdentifiers; 158 - (void)removeAllBoundaries; 159160 3.UICollisionBehavior常见用法 161 @property (nonatomic, readwrite) BOOL translatesReferenceBoundsIntoBoundary; 162 是否以参照视图的bounds为边界 163164 - (void)setTranslatesReferenceBoundsIntoBoundaryWithInsets:(UIEdgeInsets)insets; 165 设置参照视图的bounds为边界,并且设置内边距 166167 @property (nonatomic, readwrite) UICollisionBehaviorMode collisionMode; 168 碰撞模式(分为3种,元素碰撞、边界碰撞、全体碰撞) 169170 @property (nonatomic, assign, readwrite) id <UICollisionBehaviorDelegate> collisionDelegate; 171 代理对象(可以监听元素的碰撞过程) 172173 九.捕捉行为(UISnapBehavior) 174 1.简介 175 可以让物体迅速冲到某个位置(捕捉位置),捕捉到位置之后会带有一定的震动 176177 2.UISnapBehavior的初始化 178 - (instancetype)initWithItem:(id <UIDynamicItem>)item snapToPoint:(CGPoint)point; 179180 3.UISnapBehavior常见属性 181 @property (nonatomic, assign) CGFloat damping; 182 用于减幅、减震(取值范围是0.0 ~ 1.0,值越大,震动幅度越小) 183184 UISnapBehavior使用注意 185 如果要进行连续的捕捉行为,需要先把前面的捕捉行为从物理仿真器中移除 186187*/188189190 - (UIDynamicAnimator *)dynamic 191{ 192if (!_dynamic) { 193 _dynamic = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; 194 } 195return _dynamic; 196} 197198 - (void)viewDidLoad { 199 [super viewDidLoad]; 200} 201202 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event203{ 204// [self createGravity]; 205// [self createCollision];206 [self createSnap:touches]; 207208209} 210211///演示捕捉行为212 - (void)createSnap:(NSSet<UITouch *> *)touches 213{ 214//获取当前触摸的手指215 UITouch *touch = [touches anyObject]; 216//取出手指的位置217 CGPoint point = [touch locationInView:touch.view]; 218219// 1.创建物理仿真器 220221// 2.创建物理仿真行为222 UISnapBehavior *snapB = [[UISnapBehavior alloc] initWithItem:self.redView snapToPoint:point]; 223224// 3.设置捕捉行为的减震225 snapB.damping = arc4random_uniform(5) / 10 + 0.3; 226227//注意:吸附行为默认只吸附一次,如果多次吸附必须从仿真器中移除再重复添加228 [self.dynamic removeAllBehaviors]; 229230// 3.将物理仿真行为添加到物理仿真器中231 [self.dynamic addBehavior:snapB]; 232233} 234235///演示碰撞行为236 - (void)createCollision 237{ 238// 1.创建物理仿真器 239240// 2.创建物理仿真行为241 UIGravityBehavior *gravityB = [[UIGravityBehavior alloc] initWithItems:@[self.redView]]; 242 UICollisionBehavior *collisionB = [[UICollisionBehavior alloc] initWithItems:@[self.redView]]; 243244//设置碰撞边界 245// collisionB.translatesReferenceBoundsIntoBoundary = YES; 246//添加直线边界 247// [collisionB addBoundaryWithIdentifier:@"line" fromPoint:CGPointMake(0, 200) toPoint:CGPointMake(320, 420)]; 248//添加图像边界249 UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:self.view.frame]; 250251252 [collisionB addBoundaryWithIdentifier:@"bezier" forPath:path]; 253254255// 3.将物理仿真行为添加到物理仿真器中256 [self.dynamic addBehavior:gravityB]; 257 [self.dynamic addBehavior:collisionB]; 258259// 此方法可以用于碰撞实际情况的跟踪 260// collisionB.action = ^ { 261// NSLog(@"%@", NSStringFromCGRect(self.redView.frame)); 262// };263264} 265266///演示重力行为267 - (void)createGravity 268{ 269// 1.创建物理仿真器 270271// 2.创建物理仿真行为272 UIGravityBehavior *gravityB = [[UIGravityBehavior alloc] initWithItems:@[self.redView]]; 273274//设置重力方向275 gravityB.gravityDirection = CGVectorMake(0, 1); 276//设置重力角度 277//gravityB.angle = M_PI_2; 278//设置加速度279 gravityB.magnitude = 50; 280281// 3.将物理仿真行为添加到物理仿真器中282 [self.dynamic addBehavior:gravityB]; 283284} 285286@end
推动行为
1 // 2 // PushView.m 3 // 02.UIDynamic演练 4 // 5 // Created by apple on 13-12-24. 6 // Copyright (c) 2013年 itcast. All rights reserved. 7 // 8 9 #import " PushView.h " 10 11 @interface PushView() 12 { 13 UIPushBehavior *_push; 14 15// 第一次按下的点 16 CGPoint _firstPoint; 17// 移动过程中的点 18 CGPoint _movePoint; 19 20 UIImageView *_imageView; 21} 22 23@end 24 25@implementation PushView 26/* 27 皮筋效果,将方块弹射出去 28*/ 29 - (id)initWithFrame:(CGRect)frame 30{ 31 self = [super initWithFrame:frame]; 32 33if (self) { 34// 将方块下移 35 self.box.center = CGPointMake(self.center.x, 200); 36// 旋转 37 self.box.transform = CGAffineTransformMakeRotation(M_PI_4); 38 39 UIView *blueView = [[UIView alloc] initWithFrame:CGRectMake(110, 300, 20, 20)]; 40 blueView.backgroundColor = [UIColor blueColor]; 41 [self addSubview:blueView]; 42 43// 1. 定义手势 44 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)]; 45 46 [self addGestureRecognizer:pan]; 47 48// 2. 实例化推行为,单此推动 49 _push = [[UIPushBehavior alloc] initWithItems:@[self.box] mode:UIPushBehaviorModeInstantaneous]; 50 51 [self.animator addBehavior:_push]; 52 53// 3. 碰撞检测的行为 54 UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.box, blueView]]; 55 collision.translatesReferenceBoundsIntoBoundary = YES; 56 57 [self.animator addBehavior:collision]; 58 59// 4. 添加图像视图 60 UIImage *image = [UIImage imageNamed:@"AttachmentPoint_Mask"]; 61 _imageView = [[UIImageView alloc] initWithImage:image]; 62// 先隐藏 63 _imageView.hidden = YES; 64 [self addSubview:_imageView]; 65 66// iOS7添加的对图像颜色处理的功能,过滤颜色的功能 67 _imageView.tintColor = [UIColor blueColor]; 68// 重新绘图 69 _imageView.image = [_imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; 70 } 71 72return self; 73} 74 75#pragma mark - 拖动手势 76 - (void)pan:(UIPanGestureRecognizer *)recognizer 77{ 78// 取出手势所在的点 79 CGPoint location = [recognizer locationInView:self]; 80 81// 拖动手势是一个持续性手势,需要判断状态 82if (UIGestureRecognizerStateBegan == recognizer.state) { 83// 按下手指,皮筋起点在这里,需要记录住手指的位置 84 _firstPoint = location; 85 86// 添加一个图像视图标记手指按下 87 _imageView.hidden = NO; 88 _imageView.center = location; 89 90 } elseif (UIGestureRecognizerStateChanged == recognizer.state) { 91// 根据手指改变,绘制皮筋 92// 移动的点也需要记录 93 _movePoint = location; 94 95 [self setNeedsDisplay]; 96 97 } elseif (UIGestureRecognizerStateEnded == recognizer.state) { 98// 放开手指,反方向弹射方块,此时给方块一个推力 99/*100 angle 推的方向 101 magnitude 力量 102 active 单次推需要设置为YES,才能生效 103*/104 CGPoint endPoint = location; 105 CGPoint offset = CGPointMake(_firstPoint.x - endPoint.x, _firstPoint.y - endPoint.y); 106107 CGFloat distance = sqrtf(offset.x * offset.x + offset.y * offset.y); 108 CGFloat angle = atan2f(offset.y, offset.x); 109110// 推力的角度,方向111 _push.angle = angle; 112// 力量的大小113 _push.magnitude = distance / 10.0; 114115// 对于单次推动,一定要设置成YES,才能够发力116 _push.active = YES; 117118// 清理线,以及手指的图像视图119 _imageView.hidden = YES; 120 _firstPoint = CGPointZero; 121 _movePoint = CGPointZero; 122123 [self setNeedsDisplay]; 124 } 125} 126127 - (void)drawRect:(CGRect)rect 128{ 129// 1. 上下文130 CGContextRef context = UIGraphicsGetCurrentContext(); 131132// 2. 设置路径133 CGContextMoveToPoint(context, _firstPoint.x, _firstPoint.y); 134 CGContextAddLineToPoint(context, _movePoint.x, _movePoint.y); 135136// 3. 设置绘制属性137 CGContextSetLineWidth(context, 5.0); 138// 颜色139 [[UIColor darkGrayColor] set]; 140// 虚线141 CGFloat lengths[] = {20.0, 5.0}; 142 CGContextSetLineDash(context, 0.0, lengths, 2); 143144// 4. 绘图145 CGContextDrawPath(context, kCGPathStroke); 146} 147148@end
附加行为
1 // 2 // AttachmentView.m 3 // 02.UIDynamic演练 4 // 5 // Created by apple on 13-12-24. 6 // Copyright (c) 2013年 itcast. All rights reserved. 7 // 8 9 #import " AttachmentView.h " 10 11 @interface AttachmentView() 12 { 13 14 UIImageView *_anchorImage; 15 UIImageView *_offsetImage; 16} 17 18@end 19 20@implementation AttachmentView 21 22 - (id)initWithFrame:(CGRect)frame 23{ 24 self = [super initWithFrame:frame]; 25 26if (self) { 27// 下方块下移 28 self.box.center = CGPointMake(self.center.x, 200); 29 30// 手势 31 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)]; 32 33 [self addGestureRecognizer:pan]; 34 35// 附加行为 36 CGPoint anchor = CGPointMake(self.box.center.x, self.box.center.y - 100); 37 38 UIOffset offset = UIOffsetMake(0, 0); 39 40 UIAttachmentBehavior *attachment = [[UIAttachmentBehavior alloc] initWithItem:self.box offsetFromCenter:offset attachedToAnchor:anchor]; 41 42 [self.animator addBehavior:attachment]; 43 44 _attachment = attachment; 45 46// 定位点,使用一个图像视图 47 UIImage *image = [UIImage imageNamed:@"AttachmentPoint_Mask"]; 48 49 UIImageView *anchorImage = [[UIImageView alloc] initWithImage:image]; 50 anchorImage.center = anchor; 51 52 [self addSubview:anchorImage]; 53 54 _anchorImage = anchorImage; 55 56// 偏移点,轴,也是用一个图像视图 57 UIImageView *offsetImage = [[UIImageView alloc] initWithImage:image]; 58 59 CGFloat x = self.box.bounds.size.width / 2 + offset.horizontal; 60 CGFloat y = self.box.bounds.size.height / 2 + offset.vertical; 61 62 offsetImage.center = CGPointMake(x, y); 63 64 [self.box addSubview:offsetImage]; 65 66 _offsetImage = offsetImage; 67 68// 在两点之间画一条实线 69 } 70 71return self; 72} 73 74#pragma mark - 拖动手势 75 - (void)pan:(UIPanGestureRecognizer *)recognizer 76{ 77if (UIGestureRecognizerStateChanged == recognizer.state) { 78 CGPoint location = [recognizer locationInView:self]; 79 80 _attachment.anchorPoint = location; 81 _anchorImage.center = location; 82 83 [self setNeedsDisplay]; 84 } 85} 86 87 - (void)drawRect:(CGRect)rect 88{ 89 CGContextRef context = UIGraphicsGetCurrentContext(); 90 91// moveto 92 CGContextMoveToPoint(context, _anchorImage.center.x, _anchorImage.center.y); 93 94// addline 95// 去偏移点相对于父视图的坐标 96 CGPoint p = [self convertPoint:_offsetImage.center fromView:self.box]; 97 CGContextAddLineToPoint(context, p.x, p.y); 98 99 CGFloat lengths[] = {10.0f, 8.0f}; 100 CGContextSetLineDash(context, 0.0, lengths, 2); 101102 CGContextSetLineWidth(context, 5.0f); 103104 CGContextDrawPath(context, kCGPathStroke); 105} 106107108@end
原文:http://www.cnblogs.com/oc-bowen/p/5248013.html
内容总结
以上是互联网集市为您收集整理的IOS-UIDynamic全部内容,希望文章能够帮你解决IOS-UIDynamic所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。