學習地址:https://github.com/AttackOnDobby/iOS-Core-Animation-Advanced-Techniques
學習CoreAnimation 的第一步是學習CALayer,因為對一個VIew添加CoreAnimation動畫,本質(zhì)上是對view.lay進行動畫操作.
注意:動畫并不需要你在Core Animation中手動打開许布,相反需要明確地關(guān)閉,否則他會一直存在。
隱式動畫#
所謂的隱式動畫。之所以叫隱式是因為我們并沒有指定任何動畫的類型。我們僅僅改變了一個屬性丹喻,然后Core Animation來決定如何并且何時去做動畫。
本質(zhì):Core Animation在每個run loop周期中自動開始一次新的事務(wù)(run loop是iOS負責收集用戶輸入,處理定時器或者網(wǎng)絡(luò)事件并且重新繪制屏幕的東西)而晒,即使你不顯式的用[CATransaction begin]
開始一次事務(wù),任何在一次run loop循環(huán)中屬性的改變都會被集中起來阅畴,然后做一次0.25秒的動畫倡怎。
<code><pre>
@interface ViewController ()
@property (nonatomic, weak) IBOutlet UIView *layerView;
@property (nonatomic, weak) IBOutlet CALayer *colorLayer;
@end
@implementation ViewController
- (void)viewDidLoad{
[super viewDidLoad];
//create sublayer self.colorLayer = [CALayer layer];
self.colorLayer.frame = CGRectMake(50.0f, 50.0f, 100.0f, 100.0f);
self.colorLayer.backgroundColor = [UIColor blueColor].CGColor;
//add it to our view
[self.layerView.layer addSublayer:self.colorLayer];
}
- (IBAction)changeColor{
//randomize the layer background color CGFloat red = arc4random() / (CGFloat)INT_MAX;
CGFloat green = arc4random() / (CGFloat)INT_MAX;
CGFloat blue = arc4random() / (CGFloat)INT_MAX;
self.colorLayer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0].CGColor;
}
@end
</code></pre>
一:學習第一個類:CATransaction類
(transaction 英 tr?n'z?k?(?)n)有事務(wù)的意思
事務(wù) 實際上是Core Animatino 用來包含一系列屬性動畫集合的機制.任何用指定 事務(wù) 去改變可以做動畫的圖層屬性都不會立刻發(fā)生變化,而是當事務(wù)一旦 提交 的時候開始用一個動畫過渡到新值贱枣。
上面的代碼創(chuàng)建的隱式動畫就是非事務(wù)的動畫.
注意:CATransaction類不能用allloc 和init的方式創(chuàng)建,但是可以通過 +begin 和 +commit 分別來入棧和出棧.
<code><pre>
- (IBAction)changeColor{
//begin a new transaction
[CATransaction begin];
//set the animation duration to 1 second
[CATransaction setAnimationDuration:1.0];
//add the spin animation on completion
[CATransaction setCompletionBlock:^{
//rotate the layer 90 degrees
CGAffineTransform transform = self.colorLayer.affineTransform; transform = CGAffineTransformRotate(transform, M_PI_2);
self.colorLayer.affineTransform = transform;
}];
//randomize the layer background color
CGFloat red = arc4random() / (CGFloat)INT_MAX;
CGFloat green = arc4random() / (CGFloat)INT_MAX; CGFloat blue = arc4random() / (CGFloat)INT_MAX;
self.colorLayer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0].CGColor; //commit the transaction [CATransaction commit];
}
</code></pre>
注意旋轉(zhuǎn)動畫要比顏色漸變快得多监署,這是因為完成塊是在顏色漸變的事務(wù)提交并出棧之后才被執(zhí)行,于是冯事,用默認的事務(wù)做變換焦匈,默認的時間也就變成了0.25秒。
解釋:這里可以理解為兩個事務(wù),一個是改變顏色,我們設(shè)定的動畫時間是1.0秒,第二個事務(wù)就是在顏色漸變的事務(wù)提交以后,執(zhí)行的默認事務(wù)時間. 是上面提到的runloop循環(huán)處理的默認時間 0.25秒.
二:UIView圖層上的CALayer動畫
說明:之前的動畫都做在獨立的CALayer 添加到UIView上的.這里的CALayer 是和UIView關(guān)聯(lián)的CALayer 通過self.view.layer 獲取的.
UIView 上的CALayer ,UIView 都會默認成為CALayer 的CALayerDelegate代理對象.
默認實現(xiàn)了
-(id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)event{
return nil;
}
禁止了隱式動畫.這里可以理解下
當你改變CALayer的一個可做動畫的屬性昵仅,它并不能立刻在屏幕上體現(xiàn)出來缓熟。相反,它是從先前的值平滑過渡到新的值摔笤。這一切都是默認的行為够滑,你不需要做額外的操作。
我們在修改UIView中l(wèi)ayer屬性的時候,其實是默認有動畫的,只是UIView通過實現(xiàn)上面的圖層代理給禁掉了.
當然返回nil并不是禁用隱式動畫唯一的辦法吕世,CATransaction有個方法叫做+setDisableActions:彰触,可以用來對所有屬性打開或者關(guān)閉隱式動畫。如果在清單7.2的 [CATransaction begin] 之后添加下面的代碼命辖,同樣也會阻止動畫的發(fā)生:
[CATransaction setDisableActions:YES];
最重要的總結(jié)一下况毅,我們知道了如下幾點
- UIView關(guān)聯(lián)的圖層禁用了隱式動畫,對這種圖層做動畫的唯一辦法就是使用UIView的動畫函數(shù)(而不是依賴CATransaction)尔艇,或者繼承UIView尔许,并覆蓋-actionForLayer:forKey:方法,或者直接創(chuàng)建一個顯式動畫
- 對于單獨存在的圖層终娃,我們可以通過實現(xiàn)圖層的-actionForLayer:forKey:委托方法味廊,或者提供一個actions字典來控制隱式動畫。
備注: 單獨圖層的動畫,改變
<code><pre>
@interface ViewController ()
@property (nonatomic, weak) IBOutlet UIView *layerView;
@property (nonatomic, strong) CALayer *colorLayer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.colorLayer = [CALayer layer];
self.colorLayer.frame = CGRectMake(50.0f, 50.0f,200.0f, 100.0f);
self.colorLayer.backgroundColor = [UIColor blueColor].CGColor;
//add a custom action
CATransition *transition = [CATransition animation];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromLeft;
///這里對actions賦值一個自定對應(yīng)上面總結(jié)的第二點就好理解了,對獨立的圖層的背景顏色添加動畫,
//當顏色改變的時候,顏色改變時,設(shè)置的動畫
self.colorLayer.actions = @{@"backgroundColor": transition};
//add it to our view
[self.layerView.layer addSublayer:self.colorLayer];
}
- (IBAction)action:(id)sender {
CGFloat red = arc4random() / (CGFloat)INT_MAX;
CGFloat green = arc4random() / (CGFloat)INT_MAX;
CGFloat blue = arc4random() / (CGFloat)INT_MAX;
self.colorLayer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0].CGColor;
//commit the transaction
[CATransaction commit];
}
</code></pre>
呈現(xiàn)模型
暫時還無法理解,先擱下
[self.colorLayer.presentationLayer hitTest:point]
未完待續(xù)......