CABasicAnimation動畫和keypath說明

一、簡介

  • CABasicAnimation是CAPropertyAnimation的子類, CAPropertyAnimation有一個字符串類型的keyPath屬性
結(jié)構(gòu)圖-1
  • keyPath內(nèi)容是CALayer的可動畫Animatable屬性岗照,可動畫屬性可見CAlayer篇

  • 我們可以指定CALayer的某個屬性名為keyPath村象,并且對CALayer的這個屬性的值進行修改,達到相應的動畫效果攒至。

  • 例如:指定keyPath = @"position"厚者,就會修改CALayer的position屬性的值,- > 可以實現(xiàn)平移的動畫效果

  • 屬性說明: fromValue:keyPath相應屬性的初始值迫吐,toValue:keyPath相應屬性的結(jié)束值

  • 因此库菲,初始化好CAPropertyAnimation的子類對象后,必須先設置keyPath(修改的是CALayer的哪個屬性)-> 指明執(zhí)行的是怎樣的動畫(平移/縮放/旋轉(zhuǎn)等)

  • 隨著動畫的進行志膀,在長度為 duration的持續(xù)時間內(nèi)熙宇,keyPath相應屬性的值從fromValue漸漸地變?yōu)?code>toValue

  • keyPath內(nèi)容是CALayer的可動畫Animatable屬性

  • 如果fillMode=kCAFillModeForwards同時removedOnComletion=NO,那么在動畫執(zhí)行完畢后溉浙,圖層會保持顯示動畫執(zhí)行后的狀態(tài)烫止。但在實質(zhì)上,圖層的屬性值還是動畫執(zhí)行前的初始值戳稽,并沒有真正被改變馆蠕。

屬性說明:

  • duration
    動畫時長

  • fromValue
    動畫起始的位置,根據(jù)keyPath的值不一樣惊奇,這里的值也不一樣互躬;比如keyPath是position的時候,fromValue的值就是[NSValue valueWithCGPoint:<#(CGPoint)#>];

  • toValue
    動畫結(jié)束位置,和fromValue的值一致

  • repeatCount
    動畫執(zhí)行次數(shù)

  • Autoreverses
    當你設定這個屬性為 YES 時,在它到達目的地之后,動畫的返回到開始的值,代替了直接跳轉(zhuǎn)到 開始的值颂郎。

  • removedOnCompletion
    這個是在動畫結(jié)束后吼渡,是否會回到開始的值,默認是YES祖秒。如果設置為NO诞吱,則動畫結(jié)束后,會保持動畫結(jié)束后的形態(tài)竭缝,但layer的相關(guān)屬性值并沒有改變

  • Duration
    Duration 這個參數(shù)你已經(jīng)相當熟悉了。它設定開始值到結(jié)束值花費的時間沼瘫。期間會被速度的屬性所影響抬纸。 RemovedOnCompletion 這個屬性默認為 YES,那意味著,在指定的時間段完成后,動畫就自動的從層上移除了。這個一般不用耿戚。

假如你想要再次用這個動畫時,你需要設定這個屬性為 NO湿故。這樣的話,下次你在通過-set 方法設定動畫的屬 性時,它將再次使用你的動畫,而非默認的動畫阿趁。

  • Speed
    默認的值為 1.0.這意味著動畫播放按照默認的速度。如果你改變這個值為 2.0,動畫會用 2 倍的速度播放坛猪。 這樣的影響就是使持續(xù)時間減半脖阵。如果你指定的持續(xù)時間為 6 秒,速度為 2.0,動畫就會播放 3 秒鐘---一半的 持續(xù)時間。

  • BeginTime
    這個屬性在組動畫中很有用墅茉。它根據(jù)父動畫組的持續(xù)時間,指定了開始播放動畫的時間命黔。默認的是 0.0.組 動畫在下個段落中討論“Animation Grouping”。

  • TimeOffset
    如果一個時間偏移量是被設定,動畫不會真正的可見,直到根據(jù)父動畫組中的執(zhí)行時間得到的時間都流逝 了就斤。

  • RepeatCount
    默認的是 0,意味著動畫只會播放一次悍募。如果指定一個無限大的重復次數(shù),使用 1e100f。這個不應該和 repeatDration 屬性一塊使用洋机。

  • RepeatDuration
    這個屬性指定了動畫應該被重復多久坠宴。動畫會一直重復,直到設定的時間流逝完。它不應該和 repeatCount 一起使用绷旗。

keyPath屬性說明:

transform.scale = 比例轉(zhuǎn)換
transform.rotation = 旋轉(zhuǎn)
transform.rotation.x = x軸旋轉(zhuǎn)
transform.rotation.y = y軸旋轉(zhuǎn)

opacity = 透明度
margin = 邊距
position = 位移
backgroundColor = 背景顏色
cornerRadius = 圓角
borderWidth = 邊框?qū)挾?br> bounds = 位置喜鼓,體積
contents = 內(nèi)容
contentsRect = 面積
frame = 位置,體積
hidden = 是否隱藏

shadowColor = 陰影顏色
shadowOffset = 陰影偏移
shadowOpacity = 陰影透明

shadowRadius = 陰影半徑

CABasicAnimation應用:

直線進度條:

/*直線進度條*/
- (CAShapeLayer *)lineAnimationLayer
{
    if(!_lineAnimationLayer){
        _lineAnimationLayer = [CAShapeLayer layer];
        _lineAnimationLayer.strokeColor = [UIColor greenColor].CGColor;
        _lineAnimationLayer.lineWidth = 5;
//        設置路徑
        UIBezierPath * path = [UIBezierPath bezierPath];
        [path moveToPoint:CGPointMake(50, 200)];
        [path addLineToPoint:CGPointMake(300, 200)];
        _lineAnimationLayer.path = path.CGPath;
        /*動畫,keyPath是系統(tǒng)定的關(guān)鍵詞衔肢,可以自己去幫助文檔里面查看*/
        CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
//        animation的動畫時長
        animation.duration = 4.0;
//        動畫的其實位置
        animation.fromValue = @(0);
//        動畫的結(jié)束位置
        animation.toValue = @(1);
//        動畫執(zhí)行次數(shù)
        animation.repeatCount = MAXFLOAT;
//        添加動畫并設置key颠通;這個key值是自己定義的
        [_lineAnimationLayer addAnimation:animation forKey:@"lineAnimationLayer"];
    
    }
    return _lineAnimationLayer;
}

執(zhí)行結(jié)果:

進度條.gif

邊框環(huán)繞效果

實現(xiàn)代碼:

/**
 * 跑馬燈二(shaperLayer)
 */
-(void)marquee2{
    //創(chuàng)建一個shaperLayer
    CAShapeLayer *shaperLayer = [CAShapeLayer layer];
    shaperLayer.bounds = CGRectMake(0, 0, 10, 5);
    shaperLayer.position = CGPointMake((kWidth-300)/2, (kHeight-200)/2);
    shaperLayer.strokeColor = [UIColor whiteColor].CGColor;
    shaperLayer.fillColor = [UIColor clearColor].CGColor;
    shaperLayer.lineDashPattern = @[@(10),@(10)];
//    虛線結(jié)尾處的類型
    shaperLayer.lineCap = kCALineCapRound;
//    拐角處layer的類型
    shaperLayer.lineJoin = kCALineJoinRound;
    shaperLayer.lineWidth = 5;
    
    //創(chuàng)建動畫路徑
    UIBezierPath * path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 300, 200)];
    shaperLayer.path = path.CGPath;
//    CGPathRelease(path.CGPath);
    
    CAKeyframeAnimation *animation2 = [CAKeyframeAnimation animationWithKeyPath:@"strokeEnd"];
    animation2.duration = 8;
    animation2.repeatCount = MAXFLOAT;
    animation2.values = @[@(0),@(1),@(0)];
    animation2.removedOnCompletion = NO;
    animation2.fillMode = kCAFillModeForwards;
    
    /**
     * 上述的animation2的動畫和效果和下面的animation動畫效果是一樣的
     */
    CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    animation.duration = 4;
    animation.repeatCount = MAXFLOAT;
    animation.fromValue = @(0);
    animation.toValue = @(1);
//    這個設置是在一個動畫完成時,是否需要反向動畫膀懈,默認是NO
    animation.autoreverses = YES;
    
    [shaperLayer addAnimation:animation forKey:nil];
    
    [self.layer addSublayer:shaperLayer];
}

實現(xiàn)效果:

邊框環(huán)繞.gif

邊框環(huán)繞二

原理:用到兩個shaperLayer來實現(xiàn)顿锰,利用CAAnimationDelegate代理方法做處理

.h文件

/*第一個shaperLayer*/
@property (nonatomic,strong) CAShapeLayer *shaperLayer1;
/*第二個shaperLayer*/
@property (nonatomic,strong) CAShapeLayer *shaperLayer2;
/*第一個shaperLayer的動畫*/
@property (nonatomic,strong) CABasicAnimation *animation1;
/*第二個shaperLayer的動畫*/
@property (nonatomic,strong) CABasicAnimation *animation2;

.m文件

/*無到有的shaper*/
- (CAShapeLayer *)shaperLayer1
{
    if(!_shaperLayer1){
        _shaperLayer1 = [CAShapeLayer layer];
        //    shaperLayer1.position = CGPointMake((kWidth-300)/2, (kHeight-200)/2);
        _shaperLayer1.strokeColor = [UIColor whiteColor].CGColor;
        _shaperLayer1.fillColor = [UIColor clearColor].CGColor;
        _shaperLayer1.lineDashPattern = @[@(8)];
        //    結(jié)尾處的類型
        _shaperLayer1.lineCap = kCALineCapRound;
        //    拐角處的類型
        _shaperLayer1.lineJoin = kCALineJoinRound;
        _shaperLayer1.lineWidth = 5;
    }
    return _shaperLayer1;
}
/*有到無shaper*/
- (CAShapeLayer *)shaperLayer2
{
    if(!_shaperLayer2){
        _shaperLayer2 = [CAShapeLayer layer];
        //    shaperLayer2.position = CGPointMake((kWidth-300)/2, (kHeight-200)/2);
        _shaperLayer2.strokeColor = [UIColor whiteColor].CGColor;
        _shaperLayer2.fillColor = [UIColor clearColor].CGColor;
        _shaperLayer2.lineDashPattern = @[@(8)];
        //    結(jié)尾處的類型
        _shaperLayer2.lineCap = kCALineCapRound;
        //    拐角處的類型
        _shaperLayer2.lineJoin = kCALineJoinRound;
        _shaperLayer2.lineWidth = 5;
    }
    return _shaperLayer2;
}

/*注釋*/
- (CABasicAnimation *)animation1
{
    if(!_animation1){
        _animation1 = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
        _animation1.duration = 4;
        _animation1.fromValue = @(0);
        _animation1.toValue = @(1);
        _animation1.repeatCount = 1;
        _animation1.removedOnCompletion = NO;
        _animation1.fillMode = kCAFillModeForwards;
        _animation1.delegate = self;
        [_animation1 setValue:@"animation1" forKey:@"animation1"];
    }
    return _animation1;
}

/*注釋*/
- (CABasicAnimation *)animation2
{
    if(!_animation2){
        _animation2 = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
        _animation2.fromValue = @(1);
        _animation2.toValue = @(0);
        _animation2.duration = 4;
        _animation2.repeatCount = 1;
//        _animation2.autoreverses = YES;
        _animation2.removedOnCompletion = NO;
        _animation2.fillMode = kCAFillModeBackwards;
        _animation2.delegate = self;
        [_animation2 setValue:@"animation2" forKey:@"animation2"];
    }
    return _animation2;
}

- (void)marquee3{
//    創(chuàng)建路徑
    UIBezierPath * path1 = [UIBezierPath bezierPath];
    [path1 moveToPoint:CGPointMake(20, 200)];
    [path1 addLineToPoint:CGPointMake(300, 200)];
    [path1 addLineToPoint:CGPointMake(300, 400)];
    [path1 addLineToPoint:CGPointMake(20, 400)];
    [path1 closePath];
    self.shaperLayer1.path = path1.CGPath;
    
    UIBezierPath * path2 = [UIBezierPath bezierPath];
    [path2 moveToPoint:CGPointMake(20, 200)];
    [path2 addLineToPoint:CGPointMake(20, 400)];
    [path2 addLineToPoint:CGPointMake(300, 400)];
    [path2 addLineToPoint:CGPointMake(300, 200)];
    [path2 closePath];
    self.shaperLayer2.path = path2.CGPath;
//    創(chuàng)建動畫
    [self.shaperLayer1 addAnimation:self.animation1 forKey:@"animation1"];
    
    [self.layer addSublayer:self.shaperLayer1];
    [self.layer addSublayer:self.shaperLayer2];
    self.shaperLayer2.opacity = 0;
}

//動畫開始
- (void)animationDidStart:(CAAnimation *)anim{
    
}

//動畫結(jié)束
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    //判斷是不是第一個動畫
    if ([[anim valueForKey:@"animation1"] isEqualToString:@"animation1"]) {
        self.shaperLayer1.opacity = 0;
//shaperLayer1刪除掉所有動畫
        [self.shaperLayer1 removeAnimationForKey:@"animation1"];
        [self.shaperLayer2 addAnimation:self.animation2 forKey:@"animation2"];
        self.shaperLayer2.opacity = 1;
    }else{
        self.shaperLayer2.opacity = 0;
//shaperLayer2刪除所有的動畫
        [self.shaperLayer2 removeAllAnimations];
        [self.shaperLayer1 addAnimation:self.animation1 forKey:@"animation1"];
        self.shaperLayer1.opacity = 1;
    }
}

上述代碼有一段下面的代碼:

[self.shaperLayer2 removeAllAnimations];

一般在動畫結(jié)束后,layer會自動刪除掉自己的animation启搂。但是在你設置了animation的removedOnCompletion屬性為NO的時候硼控,就需要自己刪除掉layer的animation。removeAllAnimationsremoveAnimationForKey不僅有表面的意思刪除掉動畫胳赌,還有起到暫停動畫的效果牢撼,在動畫過程中實現(xiàn)這個,會使動畫暫停疑苫;

調(diào)用:

[self marquee3];

實現(xiàn)效果:

邊框環(huán)繞2.gif

這個動畫中間會跳動一下熏版,目前要想實現(xiàn)這個效果,沒有想到其他方法捍掺,有想法的朋友可以告知下撼短,這里感謝不已。

最后

這里說一個研究過程中遇到的一個問題:
問題:animation動畫結(jié)束后挺勿,會閃回到最開始狀態(tài)曲横,然后消失
解決這個問題,首先要在創(chuàng)建animation的時候,設置兩個屬性值禾嫉。分別為:

//這個屬性表示的是動畫結(jié)束后是否回到開始的狀態(tài)灾杰,默認是YES
 animation.removedOnCompletion = NO;
//這個描述的是動畫填充方式
animation.fillMode = kCAFillModeForwards;

fillMode 有下面幾個狀態(tài)值:

  • kCAFillModeRemoved 這個是默認值,也就是說當動畫開始前和動畫結(jié)束后熙参,動畫對layer都沒有影響艳吠,動畫結(jié)束后,layer會恢復到之前的狀態(tài)

  • kCAFillModeForwards 當動畫結(jié)束后孽椰,layer會一直保持著動畫最后的狀態(tài)

  • kCAFillModeBackwards 在動畫開始前昭娩,只需要將動畫加入了一個layer,layer便立即進入動畫的初始狀態(tài)并等待動畫開始弄屡。

  • kCAFillModeBoth 這個其實就是上面兩個的合成题禀,動畫加入之后在開始之前,layer便處于動畫初始狀態(tài)膀捷,動畫結(jié)束后layer保持動畫最后的狀態(tài)


其他的動畫效果可以自己嘗試下迈嘹。

CABasicAnimation的具體應用在后續(xù)的CALayer、CAShaperLayer里面都有用到

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末全庸,一起剝皮案震驚了整個濱河市秀仲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌壶笼,老刑警劉巖神僵,帶你破解...
    沈念sama閱讀 212,222評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異覆劈,居然都是意外死亡保礼,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,455評論 3 385
  • 文/潘曉璐 我一進店門责语,熙熙樓的掌柜王于貴愁眉苦臉地迎上來炮障,“玉大人,你說我怎么就攤上這事坤候⌒灿” “怎么了?”我有些...
    開封第一講書人閱讀 157,720評論 0 348
  • 文/不壞的土叔 我叫張陵白筹,是天一觀的道長智末。 經(jīng)常有香客問我,道長徒河,這世上最難降的妖魔是什么系馆? 我笑而不...
    開封第一講書人閱讀 56,568評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮虚青,結(jié)果婚禮上它呀,老公的妹妹穿的比我還像新娘。我一直安慰自己棒厘,他們只是感情好纵穿,可當我...
    茶點故事閱讀 65,696評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著奢人,像睡著了一般谓媒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上何乎,一...
    開封第一講書人閱讀 49,879評論 1 290
  • 那天句惯,我揣著相機與錄音,去河邊找鬼支救。 笑死抢野,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的各墨。 我是一名探鬼主播指孤,決...
    沈念sama閱讀 39,028評論 3 409
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼贬堵!你這毒婦竟也來了恃轩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,773評論 0 268
  • 序言:老撾萬榮一對情侶失蹤挟阻,失蹤者是張志新(化名)和其女友劉穎巩步,沒想到半個月后九默,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,220評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡筷厘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,550評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了宏所。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酥艳。...
    茶點故事閱讀 38,697評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖楣铁,靈堂內(nèi)的尸體忽然破棺而出玖雁,到底是詐尸還是另有隱情,我是刑警寧澤盖腕,帶...
    沈念sama閱讀 34,360評論 4 332
  • 正文 年R本政府宣布赫冬,位于F島的核電站,受9級特大地震影響溃列,放射性物質(zhì)發(fā)生泄漏劲厌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,002評論 3 315
  • 文/蒙蒙 一听隐、第九天 我趴在偏房一處隱蔽的房頂上張望补鼻。 院中可真熱鬧,春花似錦、人聲如沸风范。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,782評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽硼婿。三九已至锌半,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間寇漫,已是汗流浹背刊殉。 一陣腳步聲響...
    開封第一講書人閱讀 32,010評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留州胳,地道東北人记焊。 一個月前我還...
    沈念sama閱讀 46,433評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像栓撞,于是被迫代替她去往敵國和親遍膜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,587評論 2 350

推薦閱讀更多精彩內(nèi)容

  • 1 CALayer IOS SDK詳解之CALayer(一) http://doc.okbase.net/Hell...
    Kevin_Junbaozi閱讀 5,135評論 3 23
  • 如果想讓事情變得順利腐缤,只有靠自己--夏爾·紀堯姆 上一章介紹了隱式動畫的概念捌归。隱式動畫是在iOS平臺創(chuàng)建動態(tài)用戶界...
    夜空下最亮的亮點閱讀 1,933評論 0 1
  • 在iOS實際開發(fā)中常用的動畫無非是以下四種:UIView動畫,核心動畫岭粤,幀動畫惜索,自定義轉(zhuǎn)場動畫。 1.UIView...
    請叫我周小帥閱讀 3,082評論 1 23
  • 在iOS中隨處都可以看到絢麗的動畫效果剃浇,實現(xiàn)這些動畫的過程并不復雜巾兆,今天將帶大家一窺ios動畫全貌。在這里你可以看...
    每天刷兩次牙閱讀 8,471評論 6 30
  • 在iOS中隨處都可以看到絢麗的動畫效果虎囚,實現(xiàn)這些動畫的過程并不復雜角塑,今天將帶大家一窺iOS動畫全貌。在這里你可以看...
    F麥子閱讀 5,104評論 5 13