Core Animation筆記(動畫)

一.隱式動畫

layer默認開啓隱式動畫網絡

禁用隱式動畫iview

 [CATransaction setDisableActions:true];

設置隱士動畫時間dom

 //默認0.25s
    [CATransaction setAnimationDuration:3.0];

    //新啓一個事務,防止對同一時間其餘隱士動畫產生影響   動畫

 
    [CATransaction begin];
    //默認0.25s
    [CATransaction setAnimationDuration:3.0];
    //動畫完成調用塊 0.25s後調用 完成快是在事務提交以後才執行的 因此使用默認的時間0.25,後面再執行此方法是3秒後才調用
    [CATransaction setCompletionBlock:^{
        self.colorLayer.affineTransform = CGAffineTransformRotate(self.colorLayer.affineTransform, M_PI/4);
    }];
    //動畫緩衝  默認爲kCAMediaTimingFunctionLinear
  /*

    kCAMediaTimingFunctionEaseIn
    kCAMediaTimingFunctionEaseOut
    kCAMediaTimingFunctionEaseInEaseOut
    kCAMediaTimingFunctionDefault
*/
    [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
  
    CGFloat red = arc4random()*1.0/ INT_MAX;
    CGFloat green = arc4random()*1.0/ INT_MAX;
    CGFloat blue = arc4random()*1.0/ INT_MAX;

    // 
    self.colorLayer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1].CGColor;
  
    //提交事務
    [CATransaction commit];

改變actions 使其有一個過渡效果ui

  //定義過分類型這裏使背影顏色的改變是從左往右的push效果
    CATransition *transiton = [CATransition animation];
    transiton.type = kCATransitionPush;
    transiton.subtype = kCATransitionFromLeft;
    self.colorLayer = layer;
    self.colorLayer.actions = @{@"backgroundColor":transiton};

自定義action的屬性atom

當設置自定義layer的radius屬性的時候隱式的爲當前屬性添加動畫spa

 presentationLayer:獲取屏幕上真正顯示的圖層(改變圖層屬性,視覺上不是直接就顯示對應值,因此經過presentationLayer能夠獲取當前展現的圖層的信息)

   

@interface CustomActionLayer : CALayer
//當改變radius隱式的調用動畫效果
@property(nonatomic,assign)CGFloat radius;

@end
/**
 必須用dynamic,CALayer爲這個屬性自動生成存取方法 ,不能用@synthesize
 */

@dynamic radius;

- (instancetype)init{
    if (self = [super init]) {
        [self setNeedsDisplay];
    }
    return self;
}
- (void)drawInContext:(CGContextRef)ctx{
    CGContextSetFillColorWithColor(ctx,[UIColor redColor].CGColor);
    CGFloat x = self.bounds.size.width/2 - self.radius/2;
    CGFloat y = self.bounds.size.height/2 - self.radius/2;
   
    CGContextAddEllipseInRect(ctx,CGRectMake(x, y,self.radius, self.radius) );
    CGContextFillPath(ctx);
}
+ (BOOL)needsDisplayForKey:(NSString *)key{
    if ([key isEqualToString:@"radius"]) {
        return true;
    }
    return [super needsDisplayForKey:key];
    
}


/**
 presentationLayer:獲取屏幕上真正顯示的圖層(改變圖層屬性,視覺上不是直接就顯示對應值,因此經過presentationLayer能夠獲取當前展現的圖層的信息)
 */
- (id<CAAction>)actionForKey:(NSString *)event{
    if ([self presentationLayer] != nil) {
        if ([event isEqualToString:@"radius"]) {
            CABasicAnimation* basicAni = [CABasicAnimation animationWithKeyPath:@"radius"];
            basicAni.fromValue = [[self presentationLayer] valueForKey:@"radius"];
            return basicAni;
        }
    }
    return [super actionForKey:event];
    
}

 

 

 

UIView的layer默認關閉隱式動畫code

   //uiview關聯的layer禁用了隱士動畫 覆蓋了layer的actionForkey 返回nil
    [UIView beginAnimations:nil context:nil];//開啓uivew的隱士動畫
    [UIView setAnimationDuration:3.0];//這裏設置3.0秒
    self.btn.layer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1].CGColor;
    [UIView commitAnimations];

二.屬性動畫

1.CABasicAnimationorm

keyPath可取值(收集於網絡)對象

  transform.rotation.x 圍繞x軸翻轉 參數:角度 angle2Radian(4) 

  transform.rotation.y 圍繞y軸翻轉 參數:同上 

  transform.rotation.z 圍繞z軸翻轉 參數:同上 

  transform.rotation 默認圍繞z軸 

  transform.scale.x x方向縮放 參數:縮放比例 1.5 

  transform.scale.y y方向縮放 參數:同上 

  transform.scale.z z方向縮放 參數:同上 

  transform.scale 全部方向縮放 參數:同上 

  transform.translation.x x方向移動 參數:x軸上的座標 100 

  transform.translation.y x方向移動 參數:y軸上的座標 

  transform.translation.z x方向移動 參數:z軸上的座標 

  transform.translation 移動 參數:移動到的點 (100,100) 

  opacity 透明度 參數:透明度 0.5 

  backgroundColor 背景顏色 參數:顏色 (id)[[UIColor redColor] CGColor] 

  cornerRadius 圓角 參數:圓角半徑 5 

  borderWidth 邊框寬度 參數:邊框寬度 5 

  bounds 大小 參數:CGRect 

  contents 內容 參數:CGImage 

  contentsRect 可視內容 參數:CGRect 值是0~1之間的小數 

  hidden 是否隱藏 

  position 

  shadowColor 

  shadowOffset 

  shadowOpacity 

  shadowRadius

各屬性值的解釋

 

Autoreverses 設定這個屬性爲 YES 時,在它到達目的地以後,動畫的返回到開始的值,代替了直接跳轉到開始的值,過渡平滑
Duration 設定開始值到結束值花費的時間。期間會被速度的屬性所影響
RemovedOnCompletion 這個屬性默認爲 YES,在指定的時間段完成後,動畫就自動的從層上移除了。
FillMode 這個屬性通常和 RemovedOnCompletion 配合使用,保持動畫狀態。其中kCAFillModeForwards 當動畫結束後,layer會一直保持着動畫最後的狀態.此時將RemovedOnCompletion設爲NO
Speed 默認的值爲 1.0.若是你改變這個值爲 2.0,動畫會用 2 倍的速度播放。這樣的影響就是使持續時間減半。若是你指定的持續時間爲 6 秒,速度爲 2.0,動畫就會播放 3 秒鐘即一半的持續時間。
RepeatCount 默認的是 0,動畫只會播放一次。若是指定一個無限大的重複次數,使用 MAXFLOAT 。這個不該該和 repeatDration 屬性一塊使用
RepeatDuration 這個屬性指定了動畫應該被重複多久。動畫會一直重複,直到設定的時間用完。同上它不該該和 repeatCount 一塊兒使用
FromValue 設置動畫的初始值
ToValue 設置動畫的到達值
TimingFunction 控制動畫運行的節奏.    kCAMediaTimingFunctionLinear(線性):勻速,給你一個相對靜態的感受    kCAMediaTimingFunctionEaseIn(漸進):動畫緩慢進入,而後加速離開    kCAMediaTimingFunctionEaseOut(漸出):動畫全速進入,而後減速的到達目的地    kCAMediaTimingFunctionEaseInEaseOut(漸進漸出):動畫緩慢的進入,中間加速,而後減速的到達目的地。這個是默認的動畫行爲。
BeginTime 能夠用來設置動畫延遲執行時間,若想延遲1s,就設置爲CACurrentMediaTime()+1,CACurrentMediaTime()爲圖層的當前時間
    CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:@"position"];
    basic.delegate = self;
    basic.toValue = [NSValue valueWithCGPoint:point];
    basic.duration = 5.0;
//    basic.repeatCount = HUGE_VAL  //循環

 //儲存終點值用於動畫結束後獲取

    [basic setValue:[NSValue valueWithCGPoint:point] forKey:@"KBasicPostionKey"];
    [layer addAnimation:basic forKey:@"KBasicPositon"];

  basic.removedOnCompletion = false;

//位移動畫結束後回到結束的位置,若是不這麼作 視圖回到起始點  
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
 NSLog(@"animationDidStop---"); [CATransaction begin];//開啓事務
    [CATransaction setDisableActions:YES];//關閉隱式動畫
    CGPoint point = [[anim valueForKey:@"KBasicPostionKey"] CGPointValue]; layer.position = point; [CATransaction commit]; }

 

暫停動畫

    CFTimeInterval time = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
    layer.timeOffset = time;
    
 //speed = 0
    layer.speed = 0;

恢復動畫

     CFTimeInterval beigintime = CACurrentMediaTime() - layer.timeOffset;
     layer.timeOffset = 0;
     layer.beginTime = beigintime;
     layer.speed = 1

 關於動畫時間的解釋:

  

t = (tp - beginTime) * speed + offset

 t爲層上的時間,tp爲父圖層上的時間

 與圖層的層級相似,時間也有層級,修改圖層上的時間,會影響該圖層和子圖層,不影響父圖層

 CoreAnimation有一個全局時間的概念,也就是所謂的馬赫時間,它在設備上全部進程都是全局的

 圖層上的默認時間就是馬赫時間,即爲CACurrentMediaTime()

 動畫中止時,層上時間爲pauseTime

 恢復動畫時,設置了layer.speed = 1, layer.offset = 0

 t = pauseTime = (tp - beginTime) * speed + offset

 pauseTime = (CACurrentMediaTime() -  beginTime) * 1 + 0

 beginTime = CACurrentMediaTime() - pauseTime

2. CAKeyframeAnimation

基本動畫只有兩個值fromValue和toValue 而關鍵幀動畫能夠有多個值

 CAKeyframeAnimation *ani= [CAKeyframeAnimation animationWithKeyPath:@"position"];
    NSValue *key1 = [NSValue valueWithCGPoint:layer.position];
//不一樣於基本動畫關鍵幀動畫須要設置初始位置
    NSValue *key2 = [NSValue valueWithCGPoint:CGPointMake(120, 150)];
    NSValue *key3 = [NSValue valueWithCGPoint:CGPointMake(130, 300)];
    NSValue *key4 = [NSValue valueWithCGPoint:CGPointMake(110, 600)];
    ani.values = @[key1,key2,key3,key4];
    CAMediaTimingFunction *fn = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    //每一幀都運用動畫緩衝效果
    ani.timingFunctions = @[fn,fn,fn,fn];
    //自定義的緩衝,是個三次貝塞爾曲線,表明變化速率
//    ani.timingFunction = [CAMediaTimingFunction functionWithControlPoints:1 :0 :0.75 :1];
    //總體緩衝
//    ani.timingFunction = fn;
    
    ani.duration = 8;
 //    ani.beginTime = CACurrentMediaTime() +3;//延遲3秒
    [layer addAnimation:ani forKey:@"KCAFramPositon"];

 

自定義緩衝器:

定義了兩個控制點(能夠理解爲一條直線被兩個點互相吸引致使的變化) 切線表明變化速率

[CAMediaTimingFunction functionWithControlPoints:1 :0 :0.75 :1];

 

關鍵幀動畫還能夠指定運動路徑

rotationMode:當沿着路路徑變化時自動調整圖層方向
 
  CAKeyframeAnimation *ani= [CAKeyframeAnimation animationWithKeyPath:@"position"];
    
    CGMutablePathRef path = CGPathCreateMutable();
 
    CGPathMoveToPoint(path, NULL, layer.position.x, layer.position.y);
    CGPathAddCurveToPoint(path, NULL, 150, 160, -30, 80, 60, 400);
    //動畫路徑
    ani.path = path;
    //沿着路徑切線方向
    ani.rotationMode = kCAAnimationRotateAuto;
    CGPathRelease(path);//釋放路徑對象
    ani.duration = 4;
    ani.beginTime = CACurrentMediaTime() +3;//延遲3秒
    [layer addAnimation:ani forKey:@"KCAFramPositon"];

動畫組

CAAnimationGroup:

    CAAnimationGroup *group = [CAAnimationGroup animation];
    group.animations = @[ani1,ani2];

 轉場動畫

 

    CATransition *transtion = [[CATransition alloc] init];
    transtion.type = @"cube";
    transtion.subtype = kCATransitionFromRight;
    transtion.duration = 1;
    _transView.backgroundColor = bkcolors[currentIndex];
    [_transView.layer addAnimation:transtion forKey:nil];

type的值:

相關文章
相關標籤/搜索