OC开发_Storyboard——block和动画

 一、协议

@optional :可选的

@requied :必须实现的

 二、block 代码块

1、 以一个^开头,然后是参数,然后是一个大括号,包含我们的代码块

1 [aDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
2     NSLog(@“value for key %@ is %@”, key, value);
3     if ([@“ENOUGH” isEqualToString:key]) {
4         *stop = YES;
5     }
6 }];

2、如果在变量前面加上一个__block,那么这个变量就会从栈中移到堆中

 1 __block BOOL stoppedEarly = NO;
 2 double stopValue = 53.5;
 3 [aDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
 4     NSLog(@“value for key %@ is %@”, key, value);
 5     if ([@“ENOUGH” isEqualToString:key] || ([value doubleValue] == stopValue)) {
 6         *stop = YES;
 7         stoppedEarly = YES; // this is legal now
 8     }
 9 }];
10 if (stoppedEarly) NSLog(@“I stopped logging dictionary values early!”);

3、存储循环:只要Block存在block中所有的对象,就都有一个强指针指向它们

如下:block有一个强指针指向self,同时,self也有一个强指针指向block(self.myBlock)

1 [self.myBlocks addObject:^ {
2     [self doSomething];
3 }];

解决方法是:采用一个__weak类型,也就是弱类型,不会存储在堆中,没有指针指向的时候,为nil

1 __weak MyClass *weakSelf = self; //self is  strong ,  weakSelf is  weak
2 [self.myBlocks addObject:^ {
3     [weakSelf doSomething];
4 }];

4、应用:枚举、视图动画、排序、通知、错误处理、后台线程处理(多线程)

三、动画

1、三种方式:fame\transform\alpha

1 + (void)animateWithDuration:(NSTimeInterval)duration
2                       delay:(NSTimeInterval)delay
3                     options:(UIViewAnimationOptions)options
4                  animations:(void (^)(void))animations
5                  completion:(void (^)(BOOL finished))completion;

例子:

1 [UIView animateWithDuration:3.0 //代表持续多久
2                       delay:0.0 //等待多长时间开始执行
3                     options:UIViewAnimationOptionBeginFromCurrentState //拦截:这里的选项代表从当前状态,而不是又从头开始计算
4                  animations:^{ myView.alpha = 0.0; }  //执行修改等
5                  completion:^(BOOL fin) { if (fin) [myView removeFromSuperview]; }]; //bool用来判断动画是否执行完成

2、IOS7 新增的

(1 新建一个UIDunamicAnimator

(2 添加动力行为:例如重力、碰撞、推动等

(3 添加内容UIdynamicItems (这些item必须实现协议)

1 UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:aView];//新建一个UIDunamicAnimator
2
3 UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init];//添加行为
4 [animator addBehavior:gravity];
5
6 id <UIDynamicItem> item1 =  ... ;//添加内容
7 id <UIDynamicItem> item2 =  ... ;
8 [gravity addItem:item1];  [gravity addItem:item2];

如果animator正在移动但是同时要让它旋转,必须调用updateItmeUsingCurrentState方法,否则由于性能关系它会假设已知道当前的状态

3、具体的行为

(1 UIGravityBehavior  //重力行为:默认方向是向下

1 @property CGFloat angle       //角度
2 @property CGFloat magnitude   //重力大小(为1的时候代表是重力加速度)

(2 UICollisionBehavior //碰撞行为

1 @property UICollisionBehaviorMode collisionMode  //动力项:例如是相互碰撞弹开或只是从边界碰撞弹开
2 @property BOOL translatesReferenceBoundsIntoBoundary //是否为有弹性的边界

(3 UIAttachmentBehavior //吸附行为:通过它可以将一个动力项吸附到一个固定描点或另外一个动力项上

1 //初始化不用allocation或者init,而是在初始化时指定吸附对象,比如与另一个动力项、描点或者倾斜的方式等
2 @property CGFloat length //两个吸附项之间的距离
3 @property CGPoint anchorPoint

(4 UISnapBehavior  //速甩行为:使一个动力项飞速过去某个位置,到达后可能不会马上停止,或许会像弹簧一样晃动

1  //初始化的时候也是通过指定飞向的point
2  -(instancetype)initWithItme:(id <UIDynamicItme> item) snapToPoint:(CGPoint)point
3  

(5 UIPushBehavior //推动行为

1   @property UIPushBehaviorMode mode //持续的或者是瞬间的、猝发的
2   @property CGVector pushDirection  //推动的距离
3   @property CGFloat magnitude/angle  //角度或者推力大小
4   

(6 UIDynamicItemBehavior  //动力项行为类:对应上面所需要添加控制的一个类,可以通过它获取速度或者其他什么东东从而来改变现状

1 //比如说:
2   @property BOOL allowsRotation  //旋转
3   @property BOOL friction //摩擦力
4   @property BOOL elasticity //弹力、有弹性
5   @property CGFloat density  //密度

//也可以通过以下方法知道你的行为是否在执行或者是由哪个动画执行

-(void)willMoveToAnimator(UIDynamicAnimator *)animator//当行为移动到动画中,或者被移开都会调用到

(7 UIDynamicItemBehavior的action属性:相当于block,只要指定了动力项行为,每次遇到这个行为都会去执行

四 、demo

这个demo比较复杂,杂糅了动画、手势,包括重力、吸附、碰撞、摩擦、曲线、禁止旋转等是一个综合性比较强的例子,可以先看看里面应用到的代码片段

1、拖曳的手势,要注意判断3个时机

2、点击手势,掉落,这里有三个要注意的,

第一个是随机产生很的一个方块View,随机数的产生是从(0到我们背景UIView的宽度之间的大小-1)

第二个是我们要将我们最后一个方块当作我们拖曳的时候的view[这在吸附里需要取控制它的]

第三个是我们要注意动画的加入content内容,从一开始创建一个UIDunamicAnimator,然后在添加动力行为[如碰撞重力等在一个我们封装的类里面实现],最后添加内容也就是这第三步

3、吸附行为,这里有三个要注意的点,block的使用要注意变量、循环强指针引用、吸附的当前描点是不断变化的

4、动画的委托遵循UIDynamicAnimatorDelegate协议

dynamicAnimatorDidPause和dynamicAnimatorWillResume分表实现动画结束和开始的时候要做的操作

(如果没有_animator.delegate = self;是无法执行到的)

5、这里注意的是我们封装了一个dropitBehavior类,这个类专门用来封装我们的行为,

诸如我们的重力(UIGravityBehavior)、碰撞(UICollisionBehavior)、动力项行为指向(摩擦密度之类的UIDynamicItemBehavior)

在这个类操作我们控制动画的第二步,就是将这个动力行为加入到我们的动画中

6、还有我们的曲线类 BezierPathView,在我们ViewController中操作我们的曲线类的时候,是以我们UiView作为背景的,所以需要设置view的customClass为“BezierPathView”,

具体是在我们的吸附方法中使用block构造曲线,随着吸附的过程构造一个拖动的曲线。

这里不一一介绍,看demo演示:

demo下载地址:http://pan.baidu.com/s/1o69kfuM

时间: 2024-10-09 23:48:57

OC开发_Storyboard——block和动画的相关文章

OC开发_Storyboard——Core Data

一 .NSManagedObjectContext 1.我们要想操作Core Data,首先需要一个NSManagedObjectContext2.那我们如何获得Context呢:创建一个UIManagedDocument 二.UIManagedDocument 1.UIManagedDocument是一系列用于管理存储的机制:  [将Core Data数据库放入某存储空间,相当于是管理core data 数据库的存储,所以我们只需要打开和存储]2.那我们如何得到UIManagedDocumen

OC开发_Storyboard——UITableView

一.tableView 1.datasource数据源 (1 构造每一个tableVIewCell的方法:cellForRowAtIndexPath,这里的 dequeueReusableCellWithIdentifier会根据识别ID去取storyBoard中的cell,同时这也是利用取缓存中的cell复用 (2 还包含了另外两个方法,numberOfSectionsInTableView 默认是返回1如果不重写它的话:numberOfRowsInSection是没有默认值的,所以实现数据源

OC开发_Storyboard——多线程、UIScrollView

一.多线程 1.主队列:处理多点触控和所有UI操作(不能阻塞.主要同步更新UI) dispatch_queue_t mainQueue = dispatchg_get_main_queue(); //获得主线程Dispatch_async(queue ,^{ }); //异步执行Blockdispatch_queue_t Queue = dispatch_queue_create(“name”,NULL);//创建一个 2.更新UI必须在主线程中执行,有两种方法 1 //更新UI必须在主线程中执

OC开发_Storyboard——iPad开发

iPad开发(Universal Applications) 一.iPad 1.判断是否在iPad上 BOOL iPad = ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad); 二.UISplitViewController 分割视图控制器 1.UISplitViewController 分割视图控制器(顶级视图,不能放在Nav或者其他视图中) (1  可以通过 if (self.splitVie

OC开发_Storyboard——MapKit

一.Core  Location 1.基本对象 @propertys: coordinate, altitude, horizontal/verticalAccuracy, timestamp, speed, course @property (readonly) CLLocationCoordinate2D coordinate; typedef { CLLocationDegrees latitude; //   double型 纬度 CLLocationDegrees longitude;

OC开发_Storyboard——AutoLayout

一.autolayout 自动布局: 1. 设置所有视图框架的三种方法,可以通过代码创建也可以storyboard设置 = 规则 (1 蓝线+约束:(位置) 使用蓝线,根据蓝线拖动控件,只是告诉Xcode我要这样设置,但是还需要Xcode为我们执行相应的规则和约束 Reset to Sugested Constrains in VIew Controller(前提是使用了蓝线) (2 点击底部菜单按钮:Add New Alignments Constraints 具体设置(需要 update f

OC开发_Storyboard——绘制和视图

1.绘制 不要调用drawRect.调用setNeedsDisplay相当于告知系统视图需要重绘, 它会去调用drawRect,更新屏外缓冲器 2.UIBezierPath绘制图形,   设置图像opaque属性=no,根据透明度一层层合成视图,比直接修改比特值的开销会大很大多,消耗性能   如果只是显示的问题可以通过设置hidden 3.UIGestureRecognizer setNeedDisplay是为了让有人修改时重绘 ,据目标大小,选择合适尺寸 现在利用绘制做一个小demo,效果如下

OC开发_Storyboard——UIApplication和网络活动指示器

一.UIApplication 只有一个实例: UIApplication *myApplication = [UIApplication sharedApplication]; 属性如果设置为YES的话,状态栏上的小转轮就会转,NO则不会[网络活动的表示,正在进行网络活动] @property (nonatomic, getter=is...) networkActivityIndicatorVisible;

iOS动画开发之二——UIView动画执行的另一种方式

iOS动画开发之二--UIView动画执行的另一种方式 上一篇博客中介绍了UIView的一些常用动画,通过block块,我们可以很方便简洁的创建出动画效果:http://my.oschina.net/u/2340880/blog/484457,这篇博客再介绍一种更加传统的执行UIView的动画的方法. 这种方式相比如block的方式,显得要麻烦一些,apple官方也推荐我们使用带block的创建动画的方式,我们可以将编程重心更多的放在动画逻辑的实现上.使用begin和commit方式主要分为三个