一、動畫
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];
}