嗷嗚嗷嗚嗷嗚 1 // 將視圖作為屬性方便後面執行多個不同動畫 2 _myView = [[UIView alloc] init]; 3 _myView.layer.position = CGPointMake(100, 100); 4 _myView.layer.bounds = CGRectMa
嗷嗚嗷嗚嗷嗚
1 // 將視圖作為屬性方便後面執行多個不同動畫 2 _myView = [[UIView alloc] init]; 3 _myView.layer.position = CGPointMake(100, 100); 4 _myView.layer.bounds = CGRectMake(0, 0, 100, 100); 5 _myView.backgroundColor = [UIColor blueColor]; 6 [self.view addSubview:_myView]; 7 [_myView release];
1 // 創建一個CABasicAnimation類型的動畫對象並對CALayer的position屬性執行動畫 2 CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"]; 3 4 // 動畫持續1.5s 5 anim.duration = 1.5; 6 7 // position屬性值從(50, 80)漸變到(300, 350) 8 anim.fromValue = [NSValue valueWithCGPoint:CGPointMake(50, 80)]; 9 anim.toValue = [NSValue valueWithCGPoint:CGPointMake(300, 350)]; 10 11 // 設置動畫的代理 12 anim.delegate = self; 13 14 // 保持動畫執行後的狀態 15 anim.removedOnCompletion = NO; 16 anim.fillMode = kCAFillModeForwards; 17 18 // 添加動畫對象到myView的圖層上 19 [_myView.layer addAnimation:anim forKey:@"translate"];
- 上面實現了平移動畫
- 想要實現不同的效果,最關鍵的地方就是第2行CABasicAnimation對象的初始化方法中keyPath的設定。在iOS中有不同的keyPath可以查看API文檔搜索
CABasicAnimation animationWithKeyPath Types
- 第8、9行這裡的屬性接收的是id類型的參數所以不能直接使用CGPoint這種結構體類型,而是要先包裝成NSValue對象後再使用。
-
註意:可以嘗試將第9行的toValue換成byValue 區別:前者是到指定的位置,後者是在當前的位置上增加多少。
- 預設情況下,動畫執行完畢後,動畫會自動從CALayer上移除,CALayer又會回到原來的狀態。為了保持動畫執行後的狀態,可以加入第15、16行代碼
fillMode的作用就是決定當前對象過了非active時間段的行為。比如動畫開始之前,動畫結束之後。如果是一個動畫CAAnimation,則需要將其removedOnCompletion設置為NO,要不然fillMode不起作用.
kCAFillModeRemoved 預設值 也就是說當動畫開始前和動畫結束後,動畫對layer都沒有影響,動畫結束後,layer會恢復到之前的狀態
kCAFillModeForwards 當動畫結束後,layer會一直保持著動畫最後的狀態
kCAFillModeBackwards 這個和kCAFillModeForwards是相對的,就是在動畫開始前,你只要將動畫加入了一個layer,layer便立即進入動畫的初始狀態並等待動畫開始.你可以這樣設定測試代碼,將一個動畫加入一個layer的時候延遲5秒執行.然後就會發現在動畫沒有開始的時候,只要動畫被加入了layer,layer便處於動畫初始狀態
kCAFillModeBoth 理解了上面兩個,這個就很好理解了,這個其實就是上面兩個的合成.動畫加入後開始之前,layer便處於動畫初始狀態,動畫結束後layer保持動畫最後的狀態. - 第19行後面的@"translate"只是給動畫對象起了個名稱,也可以直接給個nil,但是為方便以後可以調用CALayer的removeAnimationForKey:方法根據動畫名稱來移除相應的動畫
- 第12行後面的self是視圖控制器。代理需要實現的方法:
1 #pragma mark -----動畫開始----- 2 - (void)animationDidStart:(CAAnimation *)anim { 3 NSLog(@"動畫開始了"); 4 } 5 6 #pragma mark -----動畫結束----- 7 - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { 8 // 查看一下動畫執行完畢後的position值 9 NSString *string = NSStringFromCGPoint(_myView.layer.position); 10 NSLog(@"動畫結束了,position:%@", string); 11 }
在實質上,圖層的屬性值還是動畫執行前的初始值,並沒有真正被改變。
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"];
anim.duration = 1;
CATransform3D form = CATransform3DMakeTranslation(350, 350, 0);
anim.toValue = [NSValue valueWithCATransform3D:form];
[_myView.layer addAnimation:anim forKey:nil];
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"bounds"];
anim.duration = 2;
anim.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 30, 30)];
[_myView.layer addAnimation:anim forKey:nil];
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"];
anim.duration = 1.5; // 動畫持續1.5s
// CALayer的寬度從0.5倍變為2倍
// CALayer的高度從0.5倍變為1.5倍
anim.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.5, 0.5, 1)];
anim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(2, 1.5, 1)];
[_myView.layer addAnimation:anim forKey:nil];