- 浏览: 1030088 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
繁星水:
Useful!!
Object-C之(Null)与(Bool) -
pacer123:
请问注解@ApiModelProperty 在哪个jar包下面 ...
Micro Service工具集之Swagger:可测试的样式化API文档 -
sucheng2016:
这东东真的好用么/
对象转换利器之Dozer -
zzq0324:
http://git.oschina.net/zzq0324/ ...
基于Spring-WS的Restful API的集成测试 -
lrz0534:
你好,我在maven上面下载了swagger-springmv ...
Micro Service工具集之Swagger:可测试的样式化API文档
最近在看Sam Davies写的iOS7系列文章(http://www.shinobicontrols.com/blog/posts/2013/09/19/introducing-ios7-day-by-day),非常有意思,以此为契机准备系统的学习一下iOS7的新特性, 今天是第一篇总结:UIDynamics。
UIDynamics的作用
在iOS7之前, 想要实现动画功能只有通过CoreAnimation或者UIView的Animation, 只能自己画, 对于一些真实世界中的动画行为,碰撞啊之类,实现起来特别复杂,而UIDynamic的引入就是为了简化这一类动画行为的。其将现实世界中各种物理动力驱动的动画引入了UIKit。(注:其只只引入了2D世界的物理引擎)。有了它之后,你会惊讶于可以通过如此少的代码实现这么复杂的动画效果。
UIDynamics的知识点
实例解析
下面我们就来实例解析下,如何通过UIDynamics实现一个牛顿摆(Newton's Cradle), 实现后的效果如下:
在实现一个UIDynamic动画时, 首先需要把整个的动画过程分解到各个物理动力上, 实现一个牛顿摆的物理动力有:
- 1. 重力(UIGravityBehavior)
- 2. 球和锚点之间的牵引力(UIAttachmentBehavior)
- 3. 球与球之间的碰撞(UICollisionBehavior)
- 4. 空气阻力,摩擦力等(UIDynamicItemBehavior)
- 5. 手移动球时的推动力(UIPushBehavior)
分解完动力之后,来看代码实现:
首先,创建一个球,就是一个简单的UIView,设置下形状,颜色什么的:
- (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.backgroundColor = [UIColor yellowColor]; self.layer.cornerRadius = 10; self.layer.borderColor = [UIColor redColor].CGColor; self.layer.borderWidth = 3; } return self; }
然后,创建牛顿摆的View,一个牛顿摆的界面设计的UI元素有3个, 球,锚点,球和描点的连接线,另外,为了实现UIDynamic的动画效果,需要一个UIDynamicAnimator来存储所有的DynamicBehavior,同时还有一个记录用户拉球的UIPushBehavior。
#import "NewtonsCradleView.h" @implementation NewtonsCradleView{ //球的个数 NSUInteger ballCount; //球和锚点 NSArray *_balls; NSArray *_anchors; UIDynamicAnimator *_animator; UIPushBehavior *_userDragBehavior; } - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { ballCount = 5; //初始化球和锚点 [self createBallsAndAnchors]; //添加UIDynamics动力行为 [self applyDynamicBehaviors]; } return self; } -(void)createBallsAndAnchors { NSMutableArray *ballsArray = [NSMutableArray array]; NSMutableArray *anchorsArray = [NSMutableArray array]; //估算球的大小,占屏1/3,处于屏幕中间方便用户玩 CGFloat ballSize = CGRectGetWidth(self.bounds)/(3.0*(ballCount-1)); for(int i=0; i<ballCount; i++) { BallView *ball = [[BallView alloc] initWithFrame:CGRectMake(0, 0, ballSize-1, ballSize-1)]; CGFloat x = CGRectGetWidth(self.bounds)/3.0+i*ballSize; CGFloat y = CGRectGetHeight(self.bounds)/1.5; ball.center = CGPointMake(x, y); //为球添加UIPushBehavior,支持用户拖动 UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleBallPan:)]; [ball addGestureRecognizer:panGesture]; //为球添加Oberser,当球的center属性发生改变时,会通知UIView的方法,刷新view,这儿主要是为了在球移动的时候保持锚点和球之间的连接线。 [ball addObserver:self forKeyPath:@"center" options:NSKeyValueObservingOptionNew context:Nil]; [ballsArray addObject:ball]; [self addSubview:ball]; UIView *blueBox = [self createAnchorForBall:ball]; [anchorsArray addObject:blueBox]; [self addSubview:blueBox]; } _balls = ballsArray; _anchors = anchorsArray; } - (UIView *)createAnchorForBall:(BallView *)ball { CGPoint anchor = ball.center; //根据球的位置确定描点的位置 anchor.y -= CGRectGetHeight(self.bounds) / 4.0; UIView *blueBox = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; blueBox.backgroundColor = [UIColor blueColor]; blueBox.center = anchor; return blueBox; } //处理拖动手势 -(void)handleBallPan:(UIPanGestureRecognizer *)recoginizer { //用户开始拖动时创建一个新的UIPushBehavior,并添加到animator中 if(recoginizer.state == UIGestureRecognizerStateBegan){ if (_userDragBehavior) { [_animator removeBehavior:_userDragBehavior]; } _userDragBehavior = [[UIPushBehavior alloc] initWithItems:@[recoginizer.view] mode:UIPushBehaviorModeContinuous]; [_animator addBehavior:_userDragBehavior]; } //用户完成拖动时,从animator移除PushBehavior _userDragBehavior.pushDirection = CGVectorMake([recoginizer translationInView:self].x/10.f, 0); if (recoginizer.state == UIGestureRecognizerStateEnded) { [_animator removeBehavior:_userDragBehavior]; _userDragBehavior = nil; } } #pragma mark - UIDynamics utility methods - (void)applyDynamicBehaviors { //添加UIDynamic的动力行为,同时把多个动力行为组合为一个复杂的动力行为。 UIDynamicBehavior *behavior = [[UIDynamicBehavior alloc] init]; [self applyAttachBehaviorForBalls:behavior]; [behavior addChildBehavior:[self createGravityBehaviorForObjects:_balls]]; [behavior addChildBehavior:[self createCollisionBehaviorForObjects:_balls]]; [behavior addChildBehavior:[self createItemBehavior]]; _animator = [[UIDynamicAnimator alloc] initWithReferenceView:self]; [_animator addBehavior:behavior]; } - (void)applyAttachBehaviorForBalls:(UIDynamicBehavior *)behavior { //为每个球到对应的锚点添加一个AttachmentBehavior,并作为一个子Behavior添加到一个Behavior中。 for(int i=0; i<ballCount; i++) { UIDynamicBehavior *attachmentBehavior = [self createAttachmentBehaviorForBallBearing:[_balls objectAtIndex:i] toAnchor:[_anchors objectAtIndex:i]]; [behavior addChildBehavior:attachmentBehavior]; } } - (UIDynamicBehavior *)createAttachmentBehaviorForBallBearing:(id<UIDynamicItem>)ballBearing toAnchor:(id<UIDynamicItem>)anchor { //把球attach到锚点上 UIAttachmentBehavior *behavior = [[UIAttachmentBehavior alloc] initWithItem:ballBearing attachedToAnchor:[anchor center]]; return behavior; } - (UIDynamicBehavior *)createGravityBehaviorForObjects:(NSArray *)objects { // 为所有的球添加一个重力行为 UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:objects]; gravity.magnitude = 10; return gravity; } - (UIDynamicBehavior *)createCollisionBehaviorForObjects:(NSArray *)objects { // 为所有的球添加一个碰撞行为 return [[UICollisionBehavior alloc] initWithItems:objects]; } - (UIDynamicItemBehavior *)createItemBehavior { // 为所有的球的动力行为做一个公有配置,像空气阻力,摩擦力,弹性密度等 UIDynamicItemBehavior *itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:_balls]; itemBehavior.elasticity = 1.0; itemBehavior.allowsRotation = NO; itemBehavior.resistance = 1.f; return itemBehavior; } #pragma mark - Observer -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { // Observer方法,当ball的center属性发生变化时,刷新整个view [self setNeedsDisplay]; } //覆盖父类的方法,主要是为了在锚点和球之间画一条线 -(void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); for(id<UIDynamicItem> ballBearing in _balls){ CGPoint anchor =[[_anchors objectAtIndex:[_balls indexOfObject:ballBearing]] center]; CGPoint ballCenter = [ballBearing center]; CGContextMoveToPoint(context, anchor.x, anchor.y); CGContextAddLineToPoint(context, ballCenter.x, ballCenter.y); CGContextSetLineWidth(context, 1.0f); [[UIColor blackColor] setStroke]; CGContextDrawPath(context, kCGPathFillStroke); } [self setBackgroundColor:[UIColor whiteColor]]; } //添加了Observer必须释放,不然会造成内存泄露。 -(void)dealloc { for (BallView *ball in _balls) { [ball removeObserver:self forKeyPath:@"center"]; } } @end
把上面的2个View集合在一起,弄进一个App里就可以玩了。
所有的代码在这儿:https://github.com/xianlinbox/iOS7_New
参考文章:
http://onevcat.com/2013/06/uikit-dynamics-started/
http://beyondvincent.com/blog/2013/06/16/88/
发表评论
-
Xcode的代码结构管理
2015-07-21 22:34 2713Merge Conflicts on .project fil ... -
记Protocol Oriented Programming in Swift of WWDC 2015
2015-07-12 20:28 1788其实最先朋友让我就这个题目写篇文章的时候,我是拒绝的,因为觉得 ... -
你应该知道的Core Animation知识
2015-06-07 00:04 1266分享最近读的一本书:https://github.com/At ... -
iOS7之定制View Controller切换效果
2014-04-18 23:19 38342在iOS5和iOS6前,View Controller的切换主 ... -
Object-C之(Null)与(Bool)
2014-04-05 14:08 9059在写iOS程序的时候,想初始化一个空值的时候,经常会迷茫到底是 ... -
iOS之Local Notification(本地通知)·
2014-03-23 21:31 19453Local Notification的作用 Local Not ... -
实战iOS7之后台多任务
2014-02-08 20:20 15215在WWDC2013中 水果公司把iOS7的中后台多任务单独开出 ... -
实战iOS7之NSURLSession
2014-02-01 20:19 30609NSURLSession VS NSURLConnection ... -
iOS概念之KVO(Key-Value Observing)
2014-01-26 20:21 21726在一个复杂的,有状态的系统中,当一个对象的状态发生改变,如何通 ... -
在iOS App的图标上显示版本信息
2013-12-29 19:46 5572最近读到一篇文章(http://www.merowing.in ... -
构建iOS持续集成平台
2013-09-25 20:33 5337之前写的关于iOS持续集成平台的文章终于在infoQ上发表了, ... -
Object-C的对象模型
2013-09-17 20:04 2390在Object-C的类型结构中,有几个比较重要的概念Objec ... -
使用AVAudioRecorder,AVAudioPlayer构建简单录音笔应用
2013-07-12 05:57 16868在iOS的基础类库中, 提供了AVFoundation Fra ... -
UIView的Animation效果
2013-07-05 19:05 23691所谓动画效果,就是会动的画,到iOS App中来说的话,就是各 ... -
iOS使用GameKit构建“Master-Client”网络
2013-07-02 20:34 2089GameKit是iOS SDK中一个常用的框架。其核心功能有3 ... -
Object-C中的块(Block)
2013-06-26 20:22 9162在Object-C中,块的概念 ... -
Object-C动态特性之protocol
2013-06-25 16:11 8550在Object-C中,Protocol被用来定义一组独立于具体 ... -
Object-C中的动态特性Category
2013-06-22 08:41 1678刚接触Object-C哪会儿, ... -
统一iOS客户端和服务器端认证
2013-01-18 21:05 3346最近公司的同事业余时间搞了一个内部的类about. ... -
iOS开发随笔记之 常量声明和NSUserDefaults
2012-12-09 14:19 5033在iOS中,常量声明一般使用2种方式 1、使用C语言的预处理方 ...
相关推荐
iOS 7 UI Components是iOS7组件的psd文件
iOS 7 编程实战 英文版 iOS 7 编程实战 英文版 iOS 7 编程实战 英文版 iOS 7 编程实战 英文版 iOS 7 编程实战 英文版 iOS 7 编程实战 英文版 iOS 7 编程实战 英文版 中文版也有
axure ios7 UI元件库 组件
全新版本全新工具-进击Apple IOS 13的SwiftUI开发实战,使用最新的Mac OS X集成开发工具Xcode11进行SwiftUI构建用户界面,让同学们最近的距离接触IOS与用户界面开发。课程分为了SwiftUI开发的基础部分与进阶部分,...
ios键盘 源文件 ui分层文件
iOS 7 极简风格PSD,UI开发必备
IOS7 UI界面练习 赶紧练习吧 小伙伴们
iphone ios7 UI设计素材 包括状态栏标签栏按钮图标等多种素材 适合用于ios7的UI设计和软件开发
最新的iOS8的ui包,小伙伴直接下载拿来使用吧~
Swift编程实战 iOS应用开发实例及完整解决方案 pdf 清晰版本
iOS UI 新浪微博 UI之纯代码自定义Cell实现新浪微博UI 包括自定义高度等等这些,纯UI设计,双模型
IOS7UI设计的十大准则IOS7UI设计的十大准则IOS7UI设计的十大准则
Sketch IOS UI组件库,安装即可自动加载到Sketch中,省去自己建库的时间。
iOS 7 编程实战 带书签目录 高清完整版
iOS端UI设计文档iOS端UI设计文档iOS端UI设计文档iOS端UI设计文档iOS端UI设计文档iOS端UI设计文档iOS端UI设计文档iOS端UI设计文档iOS端UI设计文档iOS端UI设计文档
关于IOS7 UI适配,介绍点方法以供大家学习
Get up to speed with the APIs introduced in iOS 7 like UIKit Dynamics, Text Kit, background fetch, and the new “flat” design! Includes over 25 chapters and 800 pages (PDF format). For intermediate...
Xamarin iOS开发实战中册
iOS 7 UI Transition Guide