GeekBand iOS开发高级进阶学习笔记(第二周)

动画效果

动画的原理来自视觉的残留效应,视觉神经反应速度约16分之1秒,只要画面变化速度快于视觉神经反应速度就会感觉是连续的,理论上10FPS(10帧每秒)就感觉动画流畅,16FPS就完全平滑。电影胶片达到了24FPS每秒,计算机显示要60FPS才能让人感觉平滑。
合理的使用动画效果可以是用户更加容易理解和使用软件,在relationship, structure, cause & effect这几个场景里是非常适合用动画的。

UIView提供的动画支持
(UIViewAnimation):depricated 已经过时iOS4之后就不再用了,遇到老的代码维护再回头看

UIView(UIViewAnimationWithBlocks)

+(void)animateWithDuration:(NSTimeInterval) delay:(NSTimeIntercal) options:(UIViewAnimationOptions) animations:(void (^)(void)) completion:(void (^__nullable)(BOOL finished));
+(void)animateWithDuration:(NSTimeInterval) animations:(void (^)(void)) completion:(void (^__nullable)(BOOL finished))
+(void)animateWithDuration:(NSTimeInterval) animations:(void (^)(void))

UIView动画的属性
frame
bounds
center
transform
alpha
backgroundColor
contentStretch

UIView的Keyframe动画支持
(UIViewKeyframeAnimations)

+(void)animateKeyframesWithDuration:(NSTimeInterval) delay:(NSTimeInterval) options:(UIViewKeyframeAnimationOptions) animations:(void (^)(void)) completion:(void (^__nullable)(BOOL finished))
+(void)animateKeyframesWithRelativeStartTime:(double) relativeDuration:(double) animations:(void (^)(void))  
//startTime和duration都是比例值,从0-1.0

Spring Animation
从iOS7开始系统开始全面使用SprintAnimation

+(void)animationWithDuration:(NSTimeInterval)duration   //总时长,一个浮点数,以秒为单位
                       delay:(NSTimeInterval)delay      //延时启动,一个浮点数,以秒为单位
      usingSpringWithDamping:(CGFloat)dampingRatio      //阻尼值0-1.0
        initalSpringVelocity:(CGFloat)velocity          //初速度
                     options:(UIViewAnimationOptions)options
                  animations:(void (^)(void))animations
                   completion:(void (^)(BOOL finished))completion

Autolayout环境下的动画
修改constraint
-[view setNeedsUpdateConstraints]
-[view layoutIfNeeded] in animation block

View Transition

View切换动画:用动画过程提示已经切换到新界面叫View Transition。
在iOS中切换动画分为两类
一类是修改子视图显示 small changes
UIView的类方法:
+transitionWithView:duration:options:animations:completion:
WithView:参数是上级View
duration:指定动画的长度
options:指定用那种类型的动画,可选参数如下

UIViewAnimationOptionTransitionNone
UIViewAnimationOptionTransitionFlipFormLeft
UIViewAnimationOptionTransitionFlipFromRight
UIViewAnimationOptionTransitionCurlUp
UIViewAnimationOptionTransitionCurlDown
UIViewAnimationOptionTransitionCrossDissolve
UIViewAnimationOptionTransitionFlipFromTop
UIViewAnimationOptionTransitionFlipFromBottom
UIViewAnimationOptionsAllowAnimatedContent //为了性能考虑,默认时动画效果是subview的一个snapshot(照相图片)来完成的,所以只能整个view动,如果view内部也需要有动画效果,就必须添加这个参数,允许Subview内部也有动画效果。

animations:一个block参数,做subview动画的管理
completion:一个block参数,可安排一些代码在动画完成后工作。

子视图类(subview)的[show, hide, add, remove]这四种情况可以用动画来显示

还有一类是视图替换:从一个场景(fromView)切换到另一个场景(toView)
类方法有:
+transitionFromView:toView:duration:options:completion:
默认的转换场景是将一个View删除,再增加一个View
也可以将两个View都添加到一个父View中,用options参数传入UIViewAnimationOptionShowHideTranstionViews这样就不会删除,直接显示一个View,隐藏另外一个View。性能更好,但是由于要同时加载两个subview内存开销较大。

Core Animation

Core Animation是iOS与OS X平台上负责图形渲染与动画的基础设施。Core Animation可以动画视图和其他的可视元素。Core Animation为你完成了实现动画所需的大部分绘帧工作。你只需在配置少量的动画参数(如开始点位置和结束点位置)就可启动Core Animation。Core Animation将大部分实际的绘图任务交给了图形硬件处理,图形硬件会加速图形渲染的速度。这种自动化的图形加速让动画具有更高的帧率且更加平滑,但这并不会增加CPU的负担而导致影响你应用的运行速度。
Core Animation是整套API,通过操作Layer来形成动画效果。
对Layer属性的修改都在CATransaction里,可以用CATransaction +begin来显示的开始一个事务。之后用CATransaction setValue:forKey来处理事务,可进行一下操作:
kCATransactionAnimationDuration;
kCATransactionDisableActions;
kCATransactionAnimationTimingFunction;
kCATransactionCompletionBlock;
处理完毕后可以用 CATransaction +commit来确认操作的修改,CATransaction操作还可以互相嵌套。

隐式动画(Implicit Animation)
只要更改了Layer的可动画属性,就会自动触发动画效果,可动画属性如下:

layer可动画属性

当我们修改属性时,Layer就会调用自身delegate中的-actionForLayer:forKey的方法,这个方法会查找对应key的CAAction和style属性,如果都没有的话会调用layer的-defaultActionForKey方法。
如果需要禁止隐式动画,只要让-actionForKey:找不到CAAction就可以了,有两种实现方法:1、在delegate中重写一个-actionForKey:方法,并且将返回值设为nil。2、调用[CATransaction setDisableActions:YES];将动画效果关闭。

显示动画
隐式动画是系统提供的我们修改不了,如果要自己设置动画效果要用到显示动画CAAnimation。
CAAnimation实现了CAAction和CAMediaTiming两个接口

显示动画

Basic Animation
CAAnimation(以及CAAnimation的子类),全部都是显式动画,这样动画播放后,表现层回恢复到模型层的原始状态,这就意味着,如果动画播放完后,会恢复到原来的样子,所以在动画播放完后要对模型层进行修改,例如:self.view.layer.backgroundColor=[UIColor blueColor].CGColor;
CABasicAnimation +animationWithKeyPath:animatableProperty
config animation
formValue:如果没有设置,则使用当前值
toValue
byValue
duration
repeatCount = HUGE_VALF; 将动画设置为无限循环
layer -addAnimation:animation forKey:animationName
set layer:property to final value:CAAnimation(以及CAAnimation的子类),全部都是显式动画,这样动画播放后,表现层回恢复到模型层的原始状态,这就意味着,如果动画播放完后,会恢复到原来的样子,所以在动画播放完后要对模型层进行修改,例如:
self.view.layer.backgroundColor=[UIColor blueColor].CGColor;

Keyframe Animation
CFKeyframeAnimation +animationWithKeyPath:animatablePropertyName-
path是一个 CGPathRef 对象,默认是空的,当我们创建好CAKeyframeAnimation的实例的时候,可以通过制定一个自己定义的path来让 某一个物体按照这个路径进行动画。这个值默认是nil 当其被设定的时候 values 这个属性就被覆盖 。
values是一个数组,提供了一组关键帧的值, 当使用path的 时候 values的值自动被忽略。

-(void)animationOfCAKeyframeAnimationPath  
{  
    //初始化一个View,用来显示动画  
    UIView *redView=[[UIView alloc]initWithFrame:CGRectMake(10, 10, 20, 20)];  
    redView.backgroundColor=[UIColor redColor];  
      
    [self.view addSubview:redView];  
      
    CAKeyframeAnimation *ani=[CAKeyframeAnimation animation];  
    //初始化路径  
    CGMutablePathRef aPath=CGPathCreateMutable();  
    //动画起始点  
    CGPathMoveToPoint(aPath, nil, 20, 20);  
    CGPathAddCurveToPoint(aPath, nil,   
                          160, 30,//控制点  
                          220, 220,//控制点   
                          240, 380);//控制点  
      
    ani.path=aPath;  
    ani.duration=10;  
    //设置为渐出  
    ani.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];  
    //自动旋转方向  
    ani.rotationMode=@"auto";  
      
    [redView.layer addAnimation:ani forKey:@"position"];  
}  

Group Animation
CAAnimationGroup +animation
agroup.animations<NSArray*>
group.duration 整个组的时间,如果在其组内的动画时长大于整组的时间,那么整组时间到之后会强制中断动画
layer -addAnimation:group:forKey:

Timing
每一个layer都有自己的time space,在彼此之间做换算可以用

-convertTime:fromLayer:
-convertTime:toLayer:
//如果设置为nil就是和系统时间做比较

所有的动画都实现了CAMediaTiming协议:

CAMediaTiming protocol

CACurrentMediaTime() 提供了系统的时间returns current system time \ mach_absolute_time() to seconds
animation.beginTime 设置了动画开始的时间,如果希望动画不是立即开始的话。

网络编程 - 原生API
TCP/IP简介

TCP/IP

推荐一个TCP/IP的介绍 http://blog.csdn.net/goodboy1881/article/category/204448

HTTP简介

HTTP

REST
是一种服务端API设计模式,使用Path指示资源,HTTP Verb表达操作。
API方法幂等(Idempotence)的概念:在设计,购买或支付等请求的时候,有时因为网络原因客户可能会多次发送同一个请求,但是只需执行一次就可以了,执行多次与执行一次效果一样,这就叫做幂等。

iOS的网络支持
Foundation (NSURL* classes) 日常使用较多
CFNetwork (core foundation 的网络设置,在做比较低层的网络控制时需要使用)
BSD Socket 最底层的网络,支持Unix的网络操作,纯C语言编写的网络操作

在iOS7以后我们都使用NSURLSession

//NSURLSession 读取URL
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:myURL
  completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
                                 {...}
]resume];

NSURLSession的结构


NSURLSession的结构

NSURLSession的基本用法
根据Session类型选择NSURLSessionConfiguration
设置Configuration,如指定NDURLCache等
用Configuration创建Session

+[NSURLSession sessionWithConfiguration:delegate:delegateQueue:] 
+[NSURLSession sessionWithConfiguration:] //简单版本

在session里创建网络访问任务
启动任务
-[NSURLSessionTask resume]
NSURLSession分为三种类型
1、Default sessions类型,用全局配置基于一个公共的文件缓存系统,把文件缓存到该文件中,用户的凭证保存在Keychain中。此方法最为常用
2、Ephemeral sessions类型,用私有的配置,文件全部缓存在内存之中,数据仅在Session期间存在。
3、Background sessions类型,另有专门的进程处理数据传输,其他跟Default一样。一般给后台应用程序使用。

Task也有三种类型
Data Task:用NSData收发数据,适合临时与服务端通信,用-[session dataTaskWithURL:]方法创建
Download Task:接受文件,支持后台下载,用-[session downloadTaskWithURL:]方法创建
Upload Task:发送文件,支持后台上传,用-[session uploadTaskWithURL:]方法创建

网络连接状态
SystemConfiguration.framework
SCNetworkReachabilityRef to host/sockaddr
SCNetworkReachabilityGetFlags()
-kSCNetworkReachabilityFlags*
SCNetworkReachabilitySetCallback()
-监听网络连接变化情况

AFNetworking

AF的全称是Alamo Fire
官方连接:https://github.com/AFNetworking/AFNetworking
目前最新版本为:3.04 (2015.4.24)
安装:可以使用CocoPods安装(CocoPods是一款Xcode系统插件管理软件)
CocoPods的安装方法:http://blog.csdn.net/showhilllee/article/details/38398119
下面用一个实例来演示一下AFNetworking的基本用法:

 // 请求的参数
 NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"20131129", @"date", @"1", @"startRecord", @"5", @"len", @"1234567890", @"udid", @"Iphone", @"terminalType", @"213", @"cid", nil];
 // 初始化Manager
 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
 
 // 不加上这句话,会报“Request failed: unacceptable content-type: text/plain”错误,因为我们要获取text/plain类型数据
 manager.responseSerializer = [AFHTTPResponseSerializer serializer];
// Get请求
 [manager GET:@"发送请求的HTTP地址" parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {
 // 这里可以获取到目前的数据请求的进度
 } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
 // 请求成功,解析数据
 NSLog(@"%@", responseObject);
 NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:nil];
 
 NSLog(@"%@", dic);
 } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
 // 请求失败
 NSLog(@"%@", [error localizedDescription]);
 }];
Get Resource
Upload

本周作业的说明
通过地图Api(高德,百度或是谷歌),对当前位置的经纬度(可以写死,非实际定位)进行网络通信,并解析数据得到当前地址。不推荐使用与地图有关的第三方库。

百度的API说明:http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding
首先要去注册一个百度的密钥:http://lbsyun.baidu.com/index.php?title=%E9%A6%96%E9%A1%B5
注册一个浏览器端密钥就可以了,如果注册iOS端秘钥,获取信息的url要记得在密钥之后加上自己的安全码,即Bundle Identifier的名字。
例如:http://api.map.baidu.com/geocoder/v2/?address=北京市海淀区上地十街10号&output=json&ak=E4805d16520de693a3fe707cdc962045&mcode=BundleIdentifier&callback=showLocation

手机自动定位功能:
首先,我们需要在工程中导入CoreLocation系统框架。然后在我们的控制器中引入头文件。

#import <CoreLocation/CoreLocation.h>

然后,声明一个CLLocationManager对象作为成员变量,用于定位获取经纬度坐标,并遵守协议

@interface TYViewController () <CLLocationManagerDelegate> {
    CLLocationManager *_locationManager;
}

开始定位

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self initializeLocationService];
    // Do any additional setup after loading the view.
}
- (void)initializeLocationService {
    // 初始化定位管理器
    _locationManager = [[CLLocationManager alloc] init];
    // 设置代理
    _locationManager.delegate = self;
    // 设置定位精确度到米
    _locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    // 设置过滤器为无
    _locationManager.distanceFilter = kCLDistanceFilterNone;
    // 开始定位
    [_locationManager startUpdatingLocation];
}

定位参考链接:http://www.2cto.com/kf/201402/279078.html

推荐阅读更多精彩内容