Core Animation 動畫的使用:關鍵幀動畫、基礎動畫、動畫組


首先讓我們了解下什么是 Core Animation,Core Animation 為核心動畫,他為圖形渲染和動畫提供了基礎。使用核心動畫,我們只需要設置起點、終點、關鍵幀等一些參數,剩下的工作核心動畫會自動幫我們處理。(學過 Flash 的朋友會有種似曾相識的感覺)

核心動畫開發動畫的本質是將 CALayer 中的內容轉換為位圖從而供硬件操作,他不用消耗 CPU 資源,合理使用他能提高 App 性能。

 

核心動畫的幾大核心類:

CAAnimation「核心動畫基類」:不能直接使用,他遵循並實現了 CAMediaTiming 協議,負責動畫運行時間和速度的控制。

CAPropertyAnimation「屬性動畫基類」:不能直接使用,他通過可動畫屬性進行動畫設置。

CAAnimationGroup「動畫組」:他是一種組合模式,可以組合多個動畫進行動畫行為的統一控制。

CATransition「轉場動畫」:主要通過濾鏡進行動畫效果設置。

CABasicAnimation「基礎動畫」:通過起點和終點狀態屬性參數進行動畫控制。

CAKeyframeAnimation「關鍵幀動畫」:同 CABasicAnimation 一樣通過屬性參數進行動畫控制,但不同的是他可以有多個狀態控制,不單單只有起點和終點。

 

CABasicAnimation 和 CAKeyframeAnimation 都屬於 CAPropertyAnimation,他們通過修改屬性參數產生動畫效果。在兩個狀態點中間過程的動畫,可以稱為「補間動畫」,他由系統自動計算產生。CABasicAnimation 只有起點和終點狀態,從某種角度來說,他相當於有兩個關鍵幀的 CAKeyframeAnimation。

 

下面讓我們通過例子,了解如何使用 CAKeyframeAnimation「關鍵幀動畫」、CABasicAnimation「基礎動畫」、CAAnimationGroup「動畫組」吧。

 

效果如下:

ViewController.h

1 #import <UIKit/UIKit.h>
2 
3 @interface ViewController : UIViewController
4 @property (strong, nonatomic) IBOutlet UIImageView *imgVAnimation;
5 @property (strong, nonatomic) IBOutlet UIButton *btnAnimation1;
6 @property (strong, nonatomic) IBOutlet UIButton *btnAnimation2;
7 
8 @end

ViewController.m

  1 #import "ViewController.h"
  2 
  3 @interface ViewController ()
  4 - (void)modifyLayerForButton:(UIButton *)btn;
  5 - (void)layoutUI;
  6 @end
  7 
  8 @implementation ViewController
  9 #define kCornerRadiusOfImage CGRectGetWidth(_imgVAnimation.frame)/2.0
 10 
 11 - (void)viewDidLoad {
 12     [super viewDidLoad];
 13     
 14     [self layoutUI];
 15 }
 16 
 17 - (void)didReceiveMemoryWarning {
 18     [super didReceiveMemoryWarning];
 19     // Dispose of any resources that can be recreated.
 20 }
 21 
 22 - (void)modifyLayerForButton:(UIButton *)btn {
 23     btn.layer.masksToBounds = YES;
 24     btn.layer.cornerRadius = 5.0;
 25     btn.layer.borderColor = [UIColor grayColor].CGColor;
 26     btn.layer.borderWidth = 1.0;
 27 }
 28 
 29 - (void)layoutUI {
 30     //圖片視圖
 31     _imgVAnimation.layer.masksToBounds = YES;
 32     _imgVAnimation.layer.cornerRadius = kCornerRadiusOfImage;
 33     _imgVAnimation.layer.borderColor = [UIColor orangeColor].CGColor;
 34     _imgVAnimation.layer.borderWidth = 2.0;
 35     
 36     //按鈕
 37     [self modifyLayerForButton:_btnAnimation1];
 38     [self modifyLayerForButton:_btnAnimation2];
 39 }
 40 
 41 - (IBAction)btnAnimation1DidPush:(id)sender {
 42     //移到右下角;使用關鍵幀動畫,移動路徑為預定的貝塞爾曲線路徑
 43     CGPoint fromPoint = _imgVAnimation.center;
 44     CGFloat toPointX = self.view.frame.size.width - kCornerRadiusOfImage;
 45     CGFloat toPointY = self.view.frame.size.height - kCornerRadiusOfImage;
 46     CGPoint toPoint = CGPointMake(toPointX, toPointY);
 47     CGPoint controlPoint = CGPointMake(toPointX, 0.0);
 48     
 49     UIBezierPath *path = [UIBezierPath bezierPath];
 50     [path moveToPoint:fromPoint];
 51     [path addQuadCurveToPoint:toPoint controlPoint:controlPoint];
 52     
 53     CAKeyframeAnimation *positionAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
 54     positionAnimation.path = path.CGPath;
 55     positionAnimation.removedOnCompletion = YES;
 56     
 57     //變小;使用基礎動畫
 58     CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
 59     transformAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
 60     transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)]; //設置 X 軸和 Y 軸縮放比例都為1.0,而 Z 軸不變
 61     transformAnimation.removedOnCompletion = YES;
 62     
 63     //透明;使用基礎動畫
 64     CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
 65     opacityAnimation.fromValue = [NSNumber numberWithFloat:1.0];
 66     opacityAnimation.toValue = [NSNumber numberWithFloat:0.1];
 67     opacityAnimation.removedOnCompletion = YES;
 68     
 69     //組合效果;使用動畫組
 70     CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
 71     animationGroup.animations = @[ positionAnimation, transformAnimation, opacityAnimation ];
 72     animationGroup.duration = 1.0; //設置動畫執行時間;這里設置為1.0秒
 73     animationGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; //設置媒體調速運動;默認為 kCAMediaTimingFunctionLinear,即為線型間隔;這里設置為 kCAMediaTimingFunctionEaseIn,即先慢后快,相當於有個加速度
 74     animationGroup.autoreverses = YES; //設置自動倒退,即動畫回放;默認值為NO
 75     [_imgVAnimation.layer addAnimation:animationGroup forKey:nil];
 76 }
 77 
 78 - (IBAction)btnAnimation2DidPush:(id)sender {
 79     //向右移動;使用關鍵幀動畫,移動路徑為預定的直線路徑
 80     CGPoint fromPoint = _imgVAnimation.center;
 81     CGPoint toPoint = CGPointMake(fromPoint.x + 100.0, fromPoint.y);
 82     
 83     UIBezierPath *path = [UIBezierPath bezierPath];
 84     [path moveToPoint:fromPoint];
 85     [path addLineToPoint:toPoint];
 86     
 87     CAKeyframeAnimation *positionAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
 88     positionAnimation.path = path.CGPath;
 89     positionAnimation.removedOnCompletion = YES;
 90     
 91     //旋轉;使用基礎動畫
 92     CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
 93     transformAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
 94     transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_2, 0.0, 0.0, 1.0)]; //設置沿着 Z 軸順時針旋轉90度;注意 CATransform3DMakeRotation 總是按最短路徑來選擇,當順時針和逆時針的路徑相同時(e.g. M_PI),會使用逆時針
 95     transformAnimation.repeatCount = 8.0; //設置動畫播放重復次數;這里設置為8.0次,共720度
 96     transformAnimation.duration = 0.5; //設置動畫執行時間;這里設置為0.5秒
 97     transformAnimation.cumulative = YES; //設置是否累積;默認值為NO,這里設置為YES,看起來才動畫效果連貫
 98     transformAnimation.removedOnCompletion = YES;
 99     
100     //組合效果;使用動畫組
101     CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
102     animationGroup.animations = @[ positionAnimation, transformAnimation ];
103     animationGroup.duration = 4.0; //設置動畫執行時間;這里設置為4.0秒
104     animationGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; //設置媒體調速運動;默認為 kCAMediaTimingFunctionLinear,即為線型間隔;這里設置為 kCAMediaTimingFunctionEaseIn,即先慢后快,相當於有個加速度
105     animationGroup.autoreverses = YES; //設置自動倒退,即動畫回放;默認值為NO
106     
107     //以下兩句是『動畫結束后回到初始狀態的現象』的解決方法;這里沒用到
108     //animationGroup.removedOnCompletion = NO; //設置是否完成后從對應的所屬圖層移除他,默認為YES
109     //animationGroup.fillMode = kCAFillModeForwards; //設置動畫填充模式;默認值為 kCAFillModeRemoved,即動畫執行完就移除,變回原來的狀態,這里設置為 kCAFillModeForwards,即保持向前的狀態
110     [_imgVAnimation.layer addAnimation:animationGroup forKey:nil];
111 }
112 
113 @end

Main.storyboard

 1 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 2 <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="vXZ-lx-hvc">
 3     <dependencies>
 4         <deployment identifier="iOS"/>
 5         <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
 6     </dependencies>
 7     <scenes>
 8         <!--View Controller-->
 9         <scene sceneID="ufC-wZ-h7g">
10             <objects>
11                 <viewController id="vXZ-lx-hvc" customClass="ViewController" sceneMemberID="viewController">
12                     <layoutGuides>
13                         <viewControllerLayoutGuide type="top" id="jyV-Pf-zRb"/>
14                         <viewControllerLayoutGuide type="bottom" id="2fi-mo-0CV"/>
15                     </layoutGuides>
16                     <view key="view" contentMode="scaleToFill" id="kh9-bI-dsS">
17                         <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
18                         <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
19                         <subviews>
20                             <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="Emoticon_tusiji_icon2" translatesAutoresizingMaskIntoConstraints="NO" id="j2r-O5-Hj2">
21                                 <rect key="frame" x="20" y="40" width="150" height="150"/>
22                             </imageView>
23                             <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="aiO-kP-xCF">
24                                 <rect key="frame" x="20" y="243" width="150" height="50"/>
25                                 <state key="normal" title="移到右下角變小透明">
26                                     <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
27                                 </state>
28                                 <connections>
29                                     <action selector="btnAnimation1DidPush:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="7Z2-yc-1vS"/>
30                                 </connections>
31                             </button>
32                             <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="圖片操作:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YH5-Oi-KEH">
33                                 <rect key="frame" x="20" y="208" width="150" height="21"/>
34                                 <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
35                                 <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
36                                 <nil key="highlightedColor"/>
37                             </label>
38                             <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="hSL-o5-Ism">
39                                 <rect key="frame" x="20" y="311" width="150" height="50"/>
40                                 <state key="normal" title="旋轉並向右移動">
41                                     <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
42                                 </state>
43                                 <connections>
44                                     <action selector="btnAnimation2DidPush:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="lC4-zx-uIb"/>
45                                 </connections>
46                             </button>
47                         </subviews>
48                         <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
49                     </view>
50                     <connections>
51                         <outlet property="btnAnimation1" destination="aiO-kP-xCF" id="kSp-82-S2R"/>
52                         <outlet property="btnAnimation2" destination="hSL-o5-Ism" id="6Mz-Wd-xfN"/>
53                         <outlet property="imgVAnimation" destination="j2r-O5-Hj2" id="Gmp-iW-kaX"/>
54                     </connections>
55                 </viewController>
56                 <placeholder placeholderIdentifier="IBFirstResponder" id="x5A-6p-PRh" sceneMemberID="firstResponder"/>
57             </objects>
58         </scene>
59     </scenes>
60     <resources>
61         <image name="Emoticon_tusiji_icon2" width="150" height="150"/>
62     </resources>
63 </document>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM