1. 程式人生 > >CABasicAnimation 給layer改變顏色不起作用的原因

CABasicAnimation 給layer改變顏色不起作用的原因

是因為對應的view bgcolor為白色

所以不起作用

去掉背景色設定就好了

還有boardercolor不起作用的另一個原因是

CABasicAnimation* selectionAnimation = [CABasicAnimation

animationWithKeyPath:@"borderColor"];

    selectionAnimation.duration = 1;

    selectionAnimation.toValue = (id)[UIColorcolorWithIntegerValue:dialog_textfield_grayalpha:1].

CGColor; //一定要設定fromValue

    selectionAnimation.fromValue = (id)[UIColorcolorWithIntegerValue:pinterest_redalpha:1].CGColor;

    selectionAnimation.removedOnCompletion = NO;

    [self.layersetBorderColor: (id)[UIColorcolorWithIntegerValue:dialog_textfield_grayalpha:1].CGColor];//因為這裡會直接設定target顏色 如果fromvalue不設定就看不到效果了

    [self.layeraddAnimation:selectionAnimation

forKey:@"borderColor"];

forkey也需要設定同樣的

下面的轉在於 http://blog.sina.com.cn/s/blog_76264a170101fdcv.html

    Apple的官方文件裡有提到,CABasicAnimation的delegate是少數會retain的delegate之一。網上介紹Core Animation的資料裡基本也都會強調這一點。

    delegate會被animation物件retain,就有可能出現retain cycle。道理誰都懂,但是實踐起來一不小心,retain cycle就在不知不覺中上了你的身。

    比如如下CABasicAnimation程式碼:

CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"];
anim.duration = 1.0f;
anim.fromValue = [NSValue numberWithCGPoint:someView.center];
anim.toValue = [NSValue numberWithCGPoint:anotherPoint];

[someView.layer addAnimation:anim forKey:@"anim"];

    很簡單的一個1.0s內將someView從原位移到anotherPoint的動畫。

    放心,這個動畫連delegate都沒有,肯定不會有retain cycle的。

    這個動畫很多時候不能滿足我們的要求,原因是當動畫結束以後,someView又回到原位去了,大多時候,我們希望的是someView留在anotherPoint的位置。

    這時我們有兩種解決方案:

    方案一是利用anim的removeOnCompletion屬性:

anim.removeOnCompletion = NO;

    這個屬性是顧名思義的。設定成NO了以後,動畫在結束後不會被移除,結合autoReverse屬性,就能做到停留在最終位置。

    方案二是在動畫加到layer上之後,人工設定view到最終位置:

[someView setCenter:anotherPoint];

    這兩種方案相比,孰優孰劣呢?

    似乎在直覺上,第二種方案的程式碼看起來更醜一點,因為如果你簡單瞭解一點Core Animation的話,你會發現,那段動畫實際上是在setCenter之後才執行的,只是你看不出來而已。既然CA給我們提供了removeOnCompletion的屬性,我們為什麼不用呢?

    似乎扯遠了,迄今為止,delegate還未出現,但是已經隱約露出了一點端倪。

    如果我們給這段動畫設定了anim.delegate = self;同時又用方案一實現了動畫結束後不移除……於是……

self持有someView,someView持有someView.layer,someView.layer持有anim,anim再持有self的話……

    終於,一個retain cycle就這樣悄悄地產生了。因為anim不會在動畫結束時被移除,所以這個retain cycle不會被打破,尤其是在ARC下,想人工break都不容易。

    假如這個動畫是迴圈的或者autoReverse的,它會一直在動,這種情況下相信所有的程式設計師都會注意到並且提醒自己,丫還沒有被釋放。但是如果是上面那種情況,估計相當一部分人就會忘了這裡還有一個已經停了的動畫的事情了。

    所以我建議,在有delegate存在的情況下,儘量還是不要用方案一來解決問題了。

    那麼方案二那麼醜怎麼辦呢……

    其實,這種情況,如果能用UIView動畫實現,為啥還要用CA呢?

[UIView beginAnimations:@"anim" context:nil];
... 動畫設定
[someView setCenter:anotherPoint];
[UIView commitAnimation];

    UIView的動畫完成之後,屬性就維持在目標狀態了。

    如果UIView動畫實在不能滿足要求,醜就醜吧……