一、动画
1.1 Core Animation构成
本周学的UIkit和Transition动画比较简单,就不在笔记中探讨了,这里主要是学习记录一下Core Animation的用法。
首先看看CoreAnimation的组成
CoreAnimation 的核心是CALayer,每个UIView都有自己的CALayer,而且每个CALayer都可以不断地添加子CALayer,CALayer所在的CALayer被称为父CALayer,CALayer的这种组织方式被称为Layer Tree。
其中:
CAAnimation:它是所有动画类的基类,它实现了CAMediaTiming协议,提供了动画的持续时间、速度和重复计数等。CA Animation还实现了CAAction协议,该协议为CALayer动画触发的动作提供标准化响应。
CAPropertyAnimation:CAAnimation 的子类,它代表一个属性动画,可以通过+animationWithKeyPath:类方法来创建属性动画实例,该方法需要指定一个CALayer支持动画的属性,然后通过它的子类控制CALayer动画属性慢慢改变,即可实现CALayer动画。
CAAnimationGroup:它是CAAnimation的子类,用于将多个动画组合在一起执行。
CATransition:CAAnimation的子类,CATransition可通过预置的过渡效果来控制CALayer层的过渡动画。
CABasicAnimation:CAPropertyAnimation的子类,简单控制CALayer层的属性慢慢改变,从而实现动画效果。很多CALayer层的属性值的修改默认会执行这个动画类,比如大小、透明度、颜色等属性。
CAKeyframeAnimation:CAPropertyAnimation的子类,支持关键帧的属性动画,该动画最大的特点在于可通过values属性指定多个关键帧,通过多个关键帧可以指定动画各阶段的关键值。
这里我们应该注意,视频中说的,所有的UIView都有一个默认的CALayer,通过UIView的layer属性即可访问UIView上的CALayer层。
1.2 CALayer的基础使用
CALayer的使用非常简单。
首先:创建一个CALayer。
然后:设置CALayer的contents属性,即可设置该CALayer所显示的内容,该属性通常可指定一个CGImage,即代表该CGLayer将要显示的图片。如果需要自行绘制该CALayer所显示的内容,则可为CALayer指定delegate属性,该属性值应该是一个实现CALayerDelegate非正式协议的对象,重写该协议中的draw Layer:inContext:方法,即可完成CALayer的绘制。
再然后:为CALayer设置backgroundColor、frame、position、anchorPoint、borderXxx、shadowXxx等属性。
最后:将该CALayer添加到父CALayer即可。
接下来,看看我做的CALayer基础使用的Deom代码:
self.view.backgroundColor=[UIColor lightGrayColor];
#pragma mark----CALayer---
self.view.layer.cornerRadius=8;
self.view.layer.borderWidth=4;
self.view.layer.borderColor=[UIColor redColor].CGColor;
#pragma mark----创建CALayer----
CALayer* subLayer=[CALayer layer];
subLayer.backgroundColor=[UIColor magentaColor].CGColor;
subLayer.cornerRadius=8;
subLayer.borderWidth=2;
subLayer.borderColor=[UIColor blackColor].CGColor;
subLayer.shadowOffset=CGSizeMake(4, 5);
subLayer.shadowColor=[UIColor blackColor].CGColor;
subLayer.shadowRadius=1;
subLayer.shadowOpacity=0.8;
subLayer.frame=CGRectMake(30, 30, 140, 160);
[self.view.layer addSublayer:subLayer];
运行的效果如下图:
1.3 CATransition控制过渡动画
CATransition通常用于通过CALayer控制UIView内子控件的过渡动画,比如,删除子控件件、添加子控件、切换两个子控件等。
使用CAtransition控制UIView内子控件的过渡动画的步骤如下:
1. 创建CATransition对象。
2.为CATransiton设置type和subtype两个属性,其中type指定动画类型,subtype指定动画移动方向
3.如果不要动画执行整个过程,则可以指定startprogress、endProgress属性。
4.调用UIView的layer属性的addAnimation:forKey:方法控制该UIView内子控件的过渡动画。addAnimation:forKey:方法的第一个参数为CAAnimation对象,第二个参数用于为该动画对象执行一个唯一标识。
下面看看用CATransiton创建一个移动控件的动画:
-(void)CATransition:(id)sender{
CATransition* transition=[CATransition animation];
transition.duration=3.0;
transition.type=kCATransitionMoveIn;
transition.subtype=kCATransitionFromLeft;
[self.Label.layer addAnimation:transition forKey:@"animation"];
self.Label.hidden=NO;
}
通过控制控件的Layer属性,实现动画效果。
1.4 CAPropertyAnimation的使用
CAPropertyAnimation是属性动画,该对象用于控制CALayer的动画属性持续改变,当CALayer的动画属性持续改变时,CALayer的外观就会持续改变——用户看上去就变成了动画。
接下来参考苹果的官方文档,主要介绍一下其拥有的属性和方法:
+(id)animationWithKeyPath:(NSString*)keyPath:该方法仅需要一个参数,该参数知识一个字符串类型的值,指定CALayer的动画属性名,设置该属性动画控制CALayer的哪个动画属性持续改变。
keyPath:该属性值返回创建CAPropertyAnimation时指定的参数。
additive:该属性置顶该属性动画是否以当前动画效果为基础。
cumulative:该属性指定动画是否为累加效果。
valueFunction:该属性值时一个CAValueFunction对象,该对象负责对属性改变的插值计算。系统已经提供了默认的插值计算方式,因此一半无需指定该属性。
如果要控制CALayer的位移动动画,则直接使用属性动画控制CALayer的position持续改变即可。如果要控制该CALayer的缩放、旋转、斜切等效果,则需要控制如下属性——affineTransform和transform。二维上的位移变化指定普通的affineTransform属性即可,三位空间的白莲花需要指定transform属性。
二、AFNetworking
2.1 认识和学习AFNetworking
首先,AFNetworking是第三方API,是一个讨人喜欢的网络库,适用于iOS以及Mac OS X. 它构建于在NSURLConnection, NSOperation, 以及其他熟悉的Foundation技术之上. 它拥有良好的架构,丰富的api,以及模块化构建方式,使得使用起来非常轻松(这句话引用自网络)
想要使用AFNetworking首先要将其部署进工程中,有两种方法,一种是手动部署,属于很基础的知识,所以不讨论了,另外一种是通过老师说的CocoaPods自动部署。
安装CocoaPods让我吃了很多苦,所以这里说一下最安装中遇到的问题,以及自己如何解决的,希望能帮到同学们。
首先我是直接一来就安装CocoaPods,肯定不成功。网上查了一下资料,说的是应该先安装Ruby环境,所以立马开始安装,又失败了。最后才知道,一开始应该最先安装rvm,通过rvm安装Ruby。所以总结一下安装步骤:
rvm->ruby->CocoaPods.
用于某系不可描述的原因,整个安装过程会极限慢,所以,大家要通过淘宝镜像进行安装。大家可以Google一下。
安装完CocoaPods大家都很激动,马上开始按照教程引入第三方库,可惜又碰到一大堆麻烦,笔者也不意外,毕竟是小白。
第一个是初次下载库文件时特别慢,但是最后我是先通过 pod update直连下载库解决的。没有挂vpn和通过国内的镜像库下载。不知道为什么,下得还是挺快的,700M大小30分钟左右就好了。所以大家安装成功CocoaPods第一件事就是 先执行 pod update下载库。
然后就是pod file文的问题。按照网上的各种攻略,和老师讲的,写好了但是报错,不能引入,最后Google到是因为CocoaPods不能找到被引入工程的Target的问题。
按照网上的教程,正确的Podfile语法应该这样写:
platform :ios, "6.0"
target "Demo" do//重点就是这句,target就是工程名。
pod 'Demo-A'//不写版本就自动下载最新
pod 'Demo-C', '~> 1.9.0'
end//记到加end,要不然要报错。
2.2 AFNetworking的基本使用方法
学习AFNetworking主要通过多看代码和反复练习,以下贴几个经常用到的函数:(非完全原创)
检测网络数据:
+ (void)netWorkStatus
{
/**
AFNetworkReachabilityStatusUnknown = -1, // 未知
AFNetworkReachabilityStatusNotReachable = 0, // 无连接
AFNetworkReachabilityStatusReachableViaWWAN = 1, // 3G
AFNetworkReachabilityStatusReachableViaWiFi = 2, // WiFi
*/
// 如果要检测网络状态的变化,必须用检测管理器的单例的startMonitoring
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
// 检测网络连接的单例,网络变化时的回调方法
[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
NSLog(@"%ld", status);
}];
}
下载文件:
+ (void)sessionDownloadWithUrl:(NSString *)urlStr success:(void (^)(NSURL *fileURL))success fail:(void (^)())fail{
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:config];
NSString *urlString = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSessionDownloadTask *task = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
// 指定下载文件保存的路径
// NSLog(@"%@ %@", targetPath, response.suggestedFilename);
// 将下载文件保存在缓存路径中
NSString *cacheDir = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
NSString *path = [cacheDir stringByAppendingPathComponent:response.suggestedFilename];
// URLWithString返回的是网络的URL,如果使用本地URL,需要注意
// NSURL *fileURL1 = [NSURL URLWithString:path];
NSURL *fileURL = [NSURL fileURLWithPath:path];
// NSLog(@"== %@ |||| %@", fileURL1, fileURL);
if (success) {
success(fileURL);
}
return fileURL;
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
NSLog(@"%@ %@", filePath, error);
if (fail) {
fail();
}
}];
[task resume];
}