(8/18)重学Standford_iOS7开发_协议、block、动画_课程笔记
第八课:
1、协议
另一种安全处理id类型的方式如:id <MyProtocol> obj
a.声明
//协议一般放于.h文件中或者在类的.h文件中 @protocol Foo <Xyzzy, NSObject>//<>中的内容表示还需实现自哪些协议,所有协议的根协议一般都是NSObject
- (void)someMethod;//默认为必须实现的方法
@optional//可选方法声明
- (void)methodWithArgument:(BOOL)argument;
@required
@property (readonly) int readonlyProperty; //只有getter在协议中
@property NSString *readwriteProperty; //getter与setter都在协议中
- (int)methodThatReturnsSomething;
@end
b.在类中实现协议
#import “Foo.h”
@interface MyClass : NSObject <Foo>
//(do not have to declare Foo’s methods again here, it’s implicit that you implement it)
@end //或者私有实现
@interface MyClass() <Foo>
@end
@implementation MyClass
//@required methods here!
@end
c.用途
①委托
②数据源
//UI与controller盲通信的方式
@property (nonatomic, weak) id <UISomeObjectDelegate> delegate;
@property (nonatomic, weak) id <UISomeObjectDataSource> dataSource;
③动画
2、Block(来源于API文档)
实际上为一段代码块,类似于C语言中的函数指针
a.声明
int multiplier = ;
int (^myBlock)(int) = ^(int num) {
return num * multiplier;
};
//int 为block返回值
//^表示为此为代码块
//myBlock为此代码块名
//int 为参数类型
//等号右边为block实现
block可以使用和他的同一范围内声明的变量,使用block与使用C函数类似
int multiplier = ;
int (^myBlock)(int) = ^(int num) {
return num * multiplier;
}; printf("%d", myBlock());
// prints "21"
b.直接使用block
block可以省略block声明直接使用
char *myCharacters[] = { "TomJohn", "George", "Charles Condomine" }; //直接使用block作为参数
qsort_b(myCharacters, , sizeof(char *), ^(const void *l, const void *r) {
char *left = *(char **)l;
char *right = *(char **)r;
return strncmp(left, right, );
}); // myCharacters is now { "Charles Condomine", "George", "TomJohn" }
c.Cocoa中使用block
NSArray *stringsArray = @[ @"string 1",
@"String 21",
@"string 12",
@"String 11",
@"String 02" ]; static NSStringCompareOptions comparisonOptions = NSCaseInsensitiveSearch | NSNumericSearch |
NSWidthInsensitiveSearch | NSForcedOrderingSearch;
NSLocale *currentLocale = [NSLocale currentLocale]; //比较器为代码块
NSComparator finderSortBlock = ^(id string1, id string2) {
NSRange string1Range = NSMakeRange(, [string1 length]);
return [string1 compare:string2 options:comparisonOptions range:string1Range locale:currentLocale];
}; NSArray *finderSortArray = [stringsArray sortedArrayUsingComparator:finderSortBlock];
NSLog(@"finderSortArray: %@", finderSortArray); /*
Output:
finderSortArray: (
"string 1",
"String 02",
"String 11",
"string 12",
"String 21"
)
*/
d.__block变量
首先看简单的例子
//直接使用变量
int x = ; void (^printXAndY)(int) = ^(int y) {
printf("%d %d\n", x, y);
}; printXAndY(); // prints: 123 456 //不可以直接更改变量,此处变量对block来说为只读
int x = ;
void (^printXAndY)(int) = ^(int y) {
x = x + y; // error
printf("%d %d\n", x, y);
};
解决方法,引入__block变量
__block int x = ; // x lives in block storage void (^printXAndY)(int) = ^(int y) {
x = x + y;
printf("%d %d\n", x, y);
};
printXAndY(); // prints: 579 456
// x is now 579
e.各种类型的变量在block中的使用
对于普通局部变量,在block声明时保存其值,之后普通局部变量的改变对block不可见
//注意block的调用时机
extern NSInteger CounterGlobal;//block对全局变量有读写权限
static NSInteger CounterStatic;//静态变量
{
NSInteger localCounter = ;//普通本地变量
__block char localCharacter;//__block本地变量 void (^aBlock)(void) = ^(void) {
++CounterGlobal;
++CounterStatic;
CounterGlobal = localCounter; // localCounter fixed at block creation
localCharacter = 'a'; // sets localCharacter in enclosing scope
}; ++localCounter; // unseen by the block,对block不可见,block的值认为42
localCharacter = 'b'; aBlock(); // execute the block
// localCharacter now 'a'
}
f.对象在block中的使用
dispatch_async(queue, ^{
/*
block中访问实例变量,instanceVariable为block所在类的实例变量,此时直接访问了实例变量,因此需要对包含它的对象(self)保留
*/
doSomethingWithObject(_instanceVariable);
}); id localVariable = _instanceVariable;
dispatch_async(queue, ^{
/*
在本地创建了指向实例变量的引用,因此需要保留localVariable而不是self
*/
doSomethingWithObject(localVariable);
});
g.使用typedef声明block
typedef float (^MyBlockType)(float, float); MyBlockType myFirstBlock = // ... ;
MyBlockType mySecondBlock = // ... ;
h.Memory Cycles
//block中引用self,所以有强指针指向self,而block又在self中定义,所以self又有强指针指向block
[self.myBlocks addObject:^ {
[self doSomething];
}];
解决方法
__weak MyClass *weakSelf = self; //重新声明为弱引用
[self.myBlocks addObject:^ {
[weakSelf doSomething];
}];
i.用途
枚举,动画,排序,通知(Notification),Error handlers,Completion handlers (错误与完成事件的处理,可以理解为回调函数),多线程等
3、动画(Animation)
a.动画的种类
Animating views :视图动画,包括移动、缩放、淡入淡出、旋转等
Animation of View Controller transitions:视图控制器动画,视图的切换等
Core Animation:核心动画框架
本节课只涉及视图动画
b.为视图添加动画的三种方法
①通过设置视图属性
frame
transform (translation, rotation and scale)
alpha (opacity)
值会立即改变,但动画效果会延时
+ (void)animateWithDuration:(NSTimeInterval)duration
delay:(NSTimeInterval)delay
options:(UIViewAnimationOptions)options
animations:(void (^)(void))animations
completion:(void (^)(BOOL finished))completion;//适用于常规动画设置
//example
[UIView animateWithDuration:3.0
delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{ myView.alpha = 0.0; }
completion:^(BOOL fin) { if (fin) [myView removeFromSuperview]; }];//视图在3秒内从父视图淡出,完成动画后并移除自己 + (void)transitionWithView:(UIView *)view
duration:(NSTimeInterval)duration
options:(UIViewAnimationOptions)options
animations:(void (^)(void))animations
completion:(void (^)(BOOL finished))completion;//适用于转场动画设置,比如卡牌的翻转 + (void)transitionFromView:(UIView *)fromView
toView:(UIView *)toView
duration:(NSTimeInterval)duration
options:(UIViewAnimationOptions)options
completion:(void (^)(BOOL finished))completion;//适用于切换视图动画
//UIViewAnimationOptions //常规动画属性设置(可以同时选择多个进行设置)
UIViewAnimationOptionLayoutSubviews //父视图变化时自动更新子视图约束@see:http://segmentfault.com/q/1010000002872390
UIViewAnimationOptionAllowUserInteraction //动画时响应用户事件,如 touch等
UIViewAnimationOptionBeginFromCurrentState //从当前状态开始动画,比如此时有动画正在改变属性
UIViewAnimationOptionRepeat //无限制重复动画
UIViewAnimationOptionAutoreverse //执行动画回路(动画运行到结束点后仍然以动画方式回到初始点),前提是设置动画无限重复
UIViewAnimationOptionOverrideInheritedDuration //忽略嵌套动画时间设置
UIViewAnimationOptionOverrideInheritedCurve //忽略嵌套动画速度设置
UIViewAnimationOptionAllowAnimatedContent //动画过程中重绘视图(注意仅仅适用于转场动画)
UIViewAnimationOptionShowHideTransitionViews //视图切换时直接隐藏旧视图、显示新视图,而不是将旧视图从父视图移除(仅仅适用于转场动画)
UIViewAnimationOptionOverrideInheritedOptions //不继承父动画设置或动画类型 //动画速度控制(可从其中选择一个设置)
UIViewAnimationOptionCurveEaseInOut //动画先缓慢,然后逐渐加速
UIViewAnimationOptionCurveEaseIn //动画逐渐变慢
UIViewAnimationOptionCurveEaseOut //动画逐渐加速
UIViewAnimationOptionCurveLinear //动画匀速执行,默认值 //转场类型(仅适用于转场动画设置,可以从中选择一个进行设置,基本动画、关键帧动画不需要设置)
UIViewAnimationOptionTransitionNone //没有转场动画效果
UIViewAnimationOptionTransitionFlipFromLeft //从左侧翻转效果
UIViewAnimationOptionTransitionFlipFromRight //从右侧翻转效果
UIViewAnimationOptionTransitionCurlUp //向后翻页的动画过渡效果
UIViewAnimationOptionTransitionCurlDown //向前翻页的动画过渡效果
UIViewAnimationOptionTransitionCrossDissolve //旧视图溶解消失显示下一个新视图的效果
UIViewAnimationOptionTransitionFlipFromTop //从上方翻转效果
UIViewAnimationOptionTransitionFlipFromBottom //从底部翻转效果
②Dynamic Animator :动力动画
实现步骤:a.创建一个UIDynamicAnimator
b.向UIDynamicAnimator添加UIDynamicBehaviors(gravity, collisions, etc.)
c.向UIDynamicAnimator添加UIDynamicItems(usually UIViews)
d.动画自动运行
//Create a UIDynamicAnimator
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:aView]; //Create and add UIDynamicBehaviors
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init];
[animator addBehavior:gravity];
UICollisionBehavior *collider = [[UICollisionBehavior alloc] init];
[animator addBehavior:collider]; //Add UIDynamicItems to a UIDynamicBehavior
id <UIDynamicItem> item1 = ...;
id <UIDynamicItem> item2 = ...;
[gravity addItem:item1];
[collider addItem:item1];
[gravity addItem:item2];
//UIDynamicItem 协议
@protocol UIDynamicItem
@property (readonly) CGRect bounds;
@property (readwrite) CGPoint center;
@property (readwrite) CGAffineTransform transform;
@end //一般UIView即可作为Item,天生实现了UIDynamic协议 //以上属性一般有动画运行时的animator来改变,若需要主动改变,需要调用
- (void)updateItemUsingCurrentState:(id <UIDynamicItem>)item;
UIDynamicBehaviors
//UIGravityBehavior
@property CGFloat angle;//重力方向,默认向下
@property CGFloat magnitude; // 1.0 is 1000 points/s/s //UICollisionBehavior 碰撞
@property UICollisionBehaviorMode collisionMode; // Items,Boundaries,Everything (default)
- (void)addBoundaryWithIdentifier:(NSString *)identifier forPath:(UIBezierPath *)path; //用UIBezierPath自定义碰撞边界
@property BOOL translatesReferenceBoundsIntoBoundary;//参考视图(动力动画的顶级视图)作为碰撞边界 //UIAttachmentBehavior 吸附行为
- (instancetype)initWithItem:(id <UIDynamicItem>)item attachedToAnchor:(CGPoint)anchor;//以点作为吸附
- (instancetype)initWithItem:(id <UIDynamicItem>)i1 attachedToItem:(id <UIDynamicItem>)i2;//以动力项作为吸附,两个动力项的吸附
- (instancetype)initWithItem:(id <UIDynamicItem>)item offsetFromCenter:(CGPoint)offset ... //偏移中心的吸附
@property (readwrite) CGFloat length; // 吸附的长度
@property (readwrite) CGPoint anchorPoint; // 吸附点
@property (readwrite, nonatomic) CGFloat damping; // 锚点移动时的阻尼
@property (readwrite, nonatomic) CGFloat frequency; // 锚点移动时的频率 //UISnapBehavior 捕捉行为
- (instancetype)initWithItem:(id <UIDynamicItem>)item snapToPoint:(CGPoint)point;
@property CGFloat damping;.//移动到锚点时振动的阻尼 //UIPushBehavior 推动行为
@property UIPushBehaviorMode mode; // Continuous or Instantaneous
@property CGVector pushDirection;
@property CGFloat magnitude/angle; // magnitude 1.0 moves a 100x100 view at 100 pts/s/s //UIDynamicItemBehavior 动力项行为,应用于所有Items
@property (readwrite, nonatomic) CGFloat elasticity; // 弹力,[0.1]
@property (readwrite, nonatomic) CGFloat friction; //摩擦力,0表示无摩擦力
@property (readwrite, nonatomic) CGFloat density; // 密度,默认为1
@property (readwrite, nonatomic) CGFloat resistance; //线性阻力系数0--CGFLOAT_MAX
@property (readwrite, nonatomic) CGFloat angularResistance; //角度阻力系数0--CGFLOAT_MAX
@property (readwrite, nonatomic) BOOL allowsRotation; //是否允许旋转
- (CGPoint)linearVelocityForItem:(id <UIDynamicItem>)item;//获取Item速度
- (CGFloat)angularVelocityForItem:(id <UIDynamicItem>)item;//获取Item角速度
创建UIDynamicBehavior子类实现自定义行为
- (void)addChildBehavior:(UIDynamicBehavior *)behavior;//将其他行为添加到自定义行为中
@property UIDynamicAnimator *dynamicAnimator;//获取当前行为所在的Animator
- (void)willMoveToAnimator:(UIDynamicAnimator *)animator;//行为加入到方法或者移除时(此时参数为nil)会调用
@property (copy) void (^action)(void);//每当行为发生时总会执行此block,注意调用比较频繁的效率问题
4、demo
Dropit:https://github.com/NSLogMeng/Stanford_iOS7_Study/commit/515b76c7ed6e74a7e30108efe6d4c833f33a6e0c
课程视频地址:网易公开课:http://open.163.com/movie/2014/1/D/L/M9H7S9F1H_M9H80D0DL.html
或者iTunes U搜索standford课程
(8/18)重学Standford_iOS7开发_协议、block、动画_课程笔记的更多相关文章
- (1/18)重学Standford_iOS7开发_iOS概述_课程笔记
写在前面:上次学习课程对iOS还是一知半解,由于缺乏实践,看公开课的视频有时不能很好地领会知识.带着问题去学习永远是最好的方法,接触一段时间iOS开发以后再来看斯坦福iOS公开课,又会有许多新的发现, ...
- (6/18)重学Standford_iOS7开发_控制器多态性、导航控制器、选项卡栏控制器_课程笔记
终于有时间跟新了,两周时间复(yu)习(xi)了5门考试累觉不爱...... ------------------------------------------------------------- ...
- (4/18)重学Standford_iOS7开发_框架和带属性字符串_课程笔记
第四课(干货课): (最近要复习考试,有点略跟不上节奏,这节课的内容还是比较重要的,仔细理解掌握对今后的编程会有很大影响) 本节课主要涉及到Foundation和UIKit框架,基本都是概念与API知 ...
- (9/18)重学Standford_iOS7开发_动画、自动布局_课程笔记
最近开始实习,没多少时间更新了=_= 第九课: 1.上节课demo:Dropit完整实现 https://github.com/NSLogMeng/Stanford_iOS7_Study/commit ...
- (7/18)重学Standford_iOS7开发_视图、绘制、手势识别_课程笔记
第七课: 1.View 一般来说,视图是一个构造块,代表屏幕上一块矩形区域,定义了一个坐标空间,并在其中绘制及添加触控事件等. ①视图的层级关系 一个视图只能有一个父视图,可以有多个子视图 - ( - ...
- (5/18)重学Standford_iOS7开发_视图控制器生命周期_课程笔记
第五课: 1.UITextView @property (nonatomic, readonly) NSTextStorage *textStorage;//注意为只读属性,因此不能直接更改内容,NS ...
- (3/18)重学Standford_iOS7开发_Objective-C_课程笔记
第三课: 本节课主要是游戏实现的demo,因此我将把课程中简单的几个编程技巧提取出来,重点介绍如何自己实现作业中的要求. 纸牌游戏实现: ①游戏的进行是模型的一部分(理解什么是模型:Model = W ...
- (2/18)重学Standford_iOS7开发_Xcode_课程笔记
第二课: 1.惰性初始化 -(ObjectType *)example { f(!_example) example =[[ObjectType alloc] init]; return _examp ...
- 重学 以太网的mac协议的CSMA/CD
之前上课一直模糊的CSMA/CD进行系统性整理. CSMA/CD (Carrier Sense Multiple Acess/Collision Detect)应用在OSI的 数据链路层 在以太网中, ...
随机推荐
- 常用webservice接口地址
天气预报Web服务,数据来源于中国气象局Endpoint :http://www.webxml.com.cn/WebServices/WeatherWebService.asmxDisco ...
- 2014年度辛星html教程夏季版第三节
接下来我们继续学习HTML中的标签,希望大家能够再接再厉,同时辛星也会支持大家,我们一起努力,一起加油.我们本小节来认识另外几个标签. *************空格和换行************** ...
- Java笔记1 : 在生产者消费者模式中,线程通信与共享数据,死锁问题与解决办法
本例定义了4个类,这里说一下,方便下面讲解.分别是Product(产品),Producer(生产者),Consumer(消费者), Test(测试类). 多线程之间通信与共享数据只要引用同一内存区域就 ...
- 双系统格式化硬盘后装XP遇到grub rescue的问题
好奇于深度的Deepin系统,给老电脑装了xp和deepin双系统.无奈07年的机子带Deepin,实在是太卡了.正好想给硬盘重新分区,直接将硬盘格式化,重装了xp.于是,问题来了,开机显示: GRU ...
- Java基础类型自动装箱(autoboxing)
Java SE 1.5 版本及之后,开始提供自动装箱功能. 自动装箱,将基础类型“包装”成一种类型: 基本类型 --> 包装器类 如下过程可触发自动装箱过程: Integer count = ...
- JQuery自学代码---(一)
/** * Created by wyl on 15-3-4. */ //Jquery是一个JavaScrioe库,它极大的简化了JavaScript编程 $(document).ready(func ...
- 移动应用产品开发-android开发(二)
这段时间实在太忙了,也没什么精力来写博客,还是没养成写博客的习惯,还是得记载下来,不然时间久了就忘记了. 早上一大早就来公司了,趁还早,拟定今天的工作内容和计划后,赶紧记载点东西. 最近做androi ...
- 李洪强漫谈iOS开发[C语言-030]-逻辑运算符
- ANDROID_MARS学习笔记_S03_009_GOOGLEMAP3
一.代码 1.xml(1)main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLay ...
- 控件构造函数需要的AOwner是TComponent,而不是Parent
普通控件都只有一个构造函数,但是这个构造函数却强迫指定AOwner,也就是说,VCL希望将所有控件(至少是所有可视化控件)全部置于它的管理之下.至于到底显示不显示,那是另一个层次的问题.这个问题其实挺 ...