IOS高級動畫詳解

CABasicAnimation 自己只有三個property   fromValue  toValue  ByValue

當你創建一個 CABasicAnimation 時,你需要通過-setFromValue 和-setToValue 來指定一個開始值和結束值。 當你增加基礎動畫到層中的時候,它開始運行。當用屬性做動畫完成時,例如用位置屬性做動畫,層就會立刻 返回到它的初始位置 

記住當你做動畫時,你至少使用了 2 個對象。這些對象都是層本身,一個層或者層繼承的對象,和在先前 的例子中你分配給層的 CABasicAnimation 對象。因爲你給動畫對象設定了最後的值(目的地),但是並不意 味着當動畫完成的時候,層的屬性就改變成了最後的值。當動畫完成時,你必須顯示的設定層的屬性,這樣動 畫結束後,你的層才能真正的到你設定的屬性值上。

你可以簡單的停止動畫到你結束的點上,但是這僅僅是一個視覺效果。層實際的值仍然是一樣的。要真的 改變內部的值,就像剛纔所說的你必須顯示的設定那個屬性。例如,顯示的設定位置的屬性,你需要在層中調 用-setPosition 方法。但是,這會造成一點問題。

如果你通過-set 這個方法顯示的設定了層屬性的值,那麼默認的動畫將被執行,而非之前你設定的動畫。 在表 3-9 中演示了你設置位置的方法。注意到了,我們使用 position 已經創建了基礎動畫,但是我們在層上顯 示的調用了-setPosition 方法,就覆蓋了我們設定的動畫,使我們設定的基礎動畫完全沒用了。如果你使用了這 個代碼,你會看到雖然我們的層結束的時候放到了正確的位置,但是它使用的是默認的 0.25 秒,而非我們在 動畫裏顯示設定的 5 秒鐘。 

1
2
3
4
CABasicAnimation *animation =
[CABasicAnimation animationWithKeyPath:@”position”]; [animation setFromValue:[NSValue valueWithPoint:startPoint]]; [animation setToValue:[NSValue valueWithPoint:endPoint]]; [animation setDuration:5.0];
[layer setPosition:endpoint];
[layer addAnimation:animation forKey:nil];

 因此現在問題出來了,你怎麼能使用我們設定的動畫呢?看錶 3-9 的最後一行,注意到 forKey:這個參數 是被設定爲 nil。這就是爲什麼動畫不能覆蓋默認動畫的原因。如果你改變最後一行爲[layer addAnimation:animation forKey:@"position"],動畫將會按照我們設定的時間工作。這告訴了層當需要做動畫時, 使用我們給關鍵路徑指定的新動畫。 

 

下面是一些繼承的屬性

Autoreverses

當你設定這個屬性爲 YES 時,在它到達目的地之後,動畫的返回到開始的值,代替了直接跳轉到 開始的值。

Duration
Duration 
這個參數你已經相當熟悉了。它設定開始值到結束值花費的時間。期間會被速度的屬性所影響。 RemovedOnCompletion
這個屬性默認爲 YES,那意味着,在指定的時間段完成後,動畫就自動的從層上移除了。這個一般不用。

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

Speed

默認的值爲 1.0.這意味着動畫播放按照默認的速度。如果你改變這個值爲 2.0,動畫會用 倍的速度播放。 這樣的影響就是使持續時間減半。如果你指定的持續時間爲 6秒,速度爲 2.0,動畫就會播放 秒鐘---一半的 持續時間。

BeginTime

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

TimeOffset

如果一個時間偏移量是被設定,動畫不會真正的可見,直到根據父動畫組中的執行時間得到的時間都流逝 了。

RepeatCount

默認的是 0,意味着動畫只會播放一次。如果指定一個無限大的重複次數,使用 1e100f。這個不應該和 repeatDration 屬性一塊使用。

RepeatDuration

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

 

 

下面這段英文摘自蘋果官方文檔,將的是fromValue  toValue  ByValue  怎麼使用

The interpolation values are used as follows:

  • Both fromValue and toValue are non-nil. Interpolates between fromValue and toValue.

  • fromValue and byValue are non-nil. Interpolates between fromValue and (fromValue + byValue).

  • byValue and toValue are non-nil. Interpolates between (toValue - byValue) and toValue.

  • fromValue is non-nil. Interpolates between fromValue and the current presentation value of the property.

  • toValue is non-nil. Interpolates between the current value of keyPath in the target layer’s presentation layer andtoValue.

  • byValue is non-nil. Interpolates between the current value of keyPath in the target layer’s presentation layer and that value plus byValue.

  • All properties are nil. Interpolates between the previous value of keyPath in the target layer’s presentation layer and the current value of keyPath in the target layer’s presentation layer.

其他的方法 還是屬性等 都是繼承而來的

我們可以通過animationWithKeyPath鍵值對的方式來改變動畫

animationWithKeyPath的值:

  transform.scale = 比例轉換

    transform.scale.x = 闊的比例轉換

    transform.scale.y = 高的比例轉換

    transform.rotation.z = 平面圖的旋轉

    opacity = 透明度

    margin

    zPosition

    backgroundColor    背景顏色

    cornerRadius    圓角

    borderWidth

    bounds

    contents

    contentsRect

    cornerRadius

    frame

    hidden

    mask

    masksToBounds

    opacity

    position

    shadowColor

    shadowOffset

    shadowOpacity

    shadowRadius

 

下面是一些例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
    CABasicAnimation *pulse = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    pulse.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    pulse.duration = 0.5 + (rand() % 10) * 0.05;
    pulse.repeatCount = 1;
    pulse.autoreverses = YES;
    pulse.fromValue = [NSNumber numberWithFloat:.8];
    pulse.toValue = [NSNumber numberWithFloat:1.2];
    [self.ui_View.layer addAnimation:pulse forKey:nil];
 
// bounds
  
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"bounds"];
    anim.duration = 1.f;
    anim.fromValue = [NSValue valueWithCGRect:CGRectMake(0,0,10,10)];
    anim.toValue = [NSValue valueWithCGRect:CGRectMake(10,10,200,200)];
    anim.byValue  = [NSValue valueWithCGRect:self. ui_View.bounds];
//    anim.toValue = (id)[UIColor redColor].CGColor;
//    anim.fromValue =  (id)[UIColor blackColor].CGColor;
     
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    anim.repeatCount = 1;
    anim.autoreverses = YES;
     
    [ui_View.layer addAnimation:anim forKey:nil];
//cornerRadius
  
    CABasicAnimation *anim2 = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
    anim2.duration = 1.f;
    anim2.fromValue = [NSNumber numberWithFloat:0.f];
    anim2.toValue = [NSNumber numberWithFloat:20.f];
    anim2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    anim2.repeatCount = CGFLOAT_MAX;
    anim2.autoreverses = YES;
     
    [ui_View.layer addAnimation:anim2 forKey:@"cornerRadius"];
 
//contents
  
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"contents"];
    anim.duration = 1.f;
    anim.fromValue = (id)[UIImage imageNamed:@"1.jpg"].CGImage;
    anim.toValue = (id)[UIImage imageNamed:@"2.png"].CGImage;
//    anim.byValue  = (id)[UIImage imageNamed:@"3.png"].CGImage;
//    anim.toValue = (id)[UIColor redColor].CGColor;
//    anim.fromValue =  (id)[UIColor blackColor].CGColor;
     
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    anim.repeatCount = CGFLOAT_MAX;
    anim.autoreverses = YES;
     
    [ui_View.layer addAnimation:anim forKey:nil];
 
 
  
[ui_View.layer setShadowOffset:CGSizeMake(2,2)];
    [ui_View.layer setShadowOpacity:1];
    [ui_View.layer setShadowColor:[UIColor grayColor].CGColor];
//
    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"shadowColor"];
    anim.duration = 1.f;
    anim.toValue = (id)[UIColor redColor].CGColor;
    anim.fromValue =  (id)[UIColor blackColor].CGColor;
     
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    anim.repeatCount = CGFLOAT_MAX;
    anim.autoreverses = YES;
     
    [ui_View.layer addAnimation:anim forKey:nil];
     
    CABasicAnimation *_anim = [CABasicAnimation animationWithKeyPath:@"shadowOffset"];
    _anim.duration = 1.f;
    _anim.fromValue = [NSValue valueWithCGSize:CGSizeMake(0,0)];
    _anim.toValue = [NSValue valueWithCGSize:CGSizeMake(3,3)];
     
    _anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    _anim.repeatCount = CGFLOAT_MAX;
    _anim.autoreverses = YES;
     
    [ui_View.layer addAnimation:_anim forKey:nil];
     
     
    CABasicAnimation *_anim1 = [CABasicAnimation animationWithKeyPath:@"shadowOpacity"];
    _anim1.duration = 1.f;
    _anim1.fromValue = [NSNumber numberWithFloat:0.5];
    _anim1.toValue = [NSNumber numberWithFloat:1];
     
    _anim1.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    _anim1.repeatCount = CGFLOAT_MAX;
    _anim1.autoreverses = YES;
     
    [ui_View.layer addAnimation:_anim1 forKey:nil];
     
     
     
    CABasicAnimation *_anim2 = [CABasicAnimation animationWithKeyPath:@"shadowRadius"];
    _anim2.duration = 1.f;
    _anim2.fromValue = [NSNumber numberWithFloat:10];
    _anim2.toValue = [NSNumber numberWithFloat:5];
     
    _anim2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    _anim2.repeatCount = CGFLOAT_MAX;
    _anim2.autoreverses = YES;
     
    [ui_View.layer addAnimation:_anim2 forKey:nil];

 下面是一些應用

 

幾個可以用來實現熱門APP應用PATH中menu效果的幾個方法
 
+(CABasicAnimation *)opacityForever_Animation:(float)time //永久閃爍的動畫
 
{
 
    CABasicAnimation *animation=[CABasicAnimation animationWithKeyPath:@"opacity"];
 
    animation.fromValue=[NSNumber numberWithFloat:1.0];
 
    animation.toValue=[NSNumber numberWithFloat:0.0];
 
    animation.autoreverses=YES;
 
    animation.duration=time;
 
    animation.repeatCount=FLT_MAX;
 
    animation.removedOnCompletion=NO;
 
    animation.fillMode=kCAFillModeForwards;
 
    return animation;
 
}
 
  
 
+(CABasicAnimation *)opacityTimes_Animation:(float)repeatTimes durTimes:(float)time; //有閃爍次數的動畫
 
{
 
    CABasicAnimation *animation=[CABasicAnimation animationWithKeyPath:@"opacity"];
 
    animation.fromValue=[NSNumber numberWithFloat:1.0];
 
    animation.toValue=[NSNumber numberWithFloat:0.4];
 
    animation.repeatCount=repeatTimes;
 
    animation.duration=time;
 
    animation.removedOnCompletion=NO;
 
    animation.fillMode=kCAFillModeForwards;
 
    animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
 
    animation.autoreverses=YES;
 
    return  animation;
 
}
 
  
 
+(CABasicAnimation *)moveX:(float)time X:(NSNumber *)x //橫向移動
 
{
 
    CABasicAnimation *animation=[CABasicAnimation animationWithKeyPath:@"transform.translation.x"];
 
    animation.toValue=x;
 
    animation.duration=time;
 
    animation.removedOnCompletion=NO;
 
    animation.fillMode=kCAFillModeForwards;
 
    return animation;
 
}
 
  
 
+(CABasicAnimation *)moveY:(float)time Y:(NSNumber *)y //縱向移動
 
{
 
    CABasicAnimation *animation=[CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
 
    animation.toValue=y;
 
    animation.duration=time;
 
    animation.removedOnCompletion=NO;
 
    animation.fillMode=kCAFillModeForwards;
 
    return animation;
 
}
 
  
 
+(CABasicAnimation *)scale:(NSNumber *)Multiple orgin:(NSNumber *)orginMultiple durTimes:(float)time Rep:(float)repeatTimes //縮放
 
{
 
    CABasicAnimation *animation=[CABasicAnimation animationWithKeyPath:@"transform.scale"];
 
    animation.fromValue=orginMultiple;
 
    animation.toValue=Multiple;
 
    animation.duration=time;
 
    animation.autoreverses=YES;
 
    animation.repeatCount=repeatTimes;
 
    animation.removedOnCompletion=NO;
 
    animation.fillMode=kCAFillModeForwards;
 
    return animation;
 
}
 
  
 
+(CAAnimationGroup *)groupAnimation:(NSArray *)animationAry durTimes:(float)time Rep:(float)repeatTimes //組合動畫
 
{
 
    CAAnimationGroup *animation=[CAAnimationGroup animation];
 
    animation.animations=animationAry;
 
    animation.duration=time;
 
    animation.repeatCount=repeatTimes;
 
    animation.removedOnCompletion=NO;
 
    animation.fillMode=kCAFillModeForwards;
 
    return animation;
 
}
 
  
 
+(CAKeyframeAnimation *)keyframeAniamtion:(CGMutablePathRef)path durTimes:(float)time Rep:(float)repeatTimes //路徑動畫
 
{
 
    CAKeyframeAnimation *animation=[CAKeyframeAnimation animationWithKeyPath:@"position"];
 
    animation.path=path;
 
    animation.removedOnCompletion=NO;
 
    animation.fillMode=kCAFillModeForwards;
 
    animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
 
    animation.autoreverses=NO;
 
    animation.duration=time;
 
    animation.repeatCount=repeatTimes;
 
    return animation;
 
}
 
  
 
+(CABasicAnimation *)movepoint:(CGPoint )point //點移動
 
{
 
    CABasicAnimation *animation=[CABasicAnimation animationWithKeyPath:@"transform.translation"];
 
    animation.toValue=[NSValue valueWithCGPoint:point];
 
    animation.removedOnCompletion=NO;
 
    animation.fillMode=kCAFillModeForwards;
 
    return animation;
 
}
 
  
 
+(CABasicAnimation *)rotation:(float)dur degree:(float)degree direction:(int)direction repeatCount:(int)repeatCount //旋轉
 
{
 
    CATransform3D rotationTransform  = CATransform3DMakeRotation(degree, 0, 0,direction);
 
    CABasicAnimation* animation;
 
    animation = [CABasicAnimation animationWithKeyPath:@"transform"];
 
  
 
animation.toValue= [NSValue valueWithCATransform3D:rotationTransform];
 
    animation.duration= dur;
 
animation.autoreverses= NO;
 
    animation.cumulative= YES;
 
    animation.removedOnCompletion=NO;
 
    animation.fillMode=kCAFillModeForwards;
 
    animation.repeatCount= repeatCount;
 
animation.delegate= self;
 
  
 
return animation;
 
}
發佈了92 篇原創文章 · 獲贊 11 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章