Core Animation(五)显式动画

隐式动画虽然能够实现动画效果,但并不能涵盖所有的动画类型。很多复杂的动画是需要我们自定义动画的, 它能够对一些属性做指定 的自定义动画,或者创建非线性动画,比如沿着任意一条曲线移动。
显示动画主要是由CAAnimation类提供,而我们主要使用CAAnimation的四个子类,下面做一一介绍。



  1. 属性动画:CAPropertyAnimaition

  • 基础动画CABasicAnimation
  • 关键帧动画CAKeyframeAnimation

CABasicAnimation:基础动画主要有三个属性,fromValue,toValue,byValue。不过三个属性被封装成对象。

缺点:由于显式动画只是一段动画效果,不会改变属性的真正状态,所以需要我们手动在动画效果后重新设置属性的值。
一般对属性赋新值可以在两个位置,1.在动画效果之前  2.在动画效果之后。而在动画效果之前改变属性值比较简单。

在动画效果之前改变属性值需要注意两个点:

  1. 改变属性值最好关闭隐式动画(虽然显式动画会覆盖隐式动画)
  2. 做动画的图层是从当前图层还是模型图层开始。

- (void)applyBasicAnimation:(CABasicAnimation *)animation toLayer:(CALayer *)layer
{
    //set the from value (using presentation layer if available)
    animation. fromValue = [layer. presentationLayer ?: layer         //  ——— 2
                           valueForKeyPath:animation.keyPath];   
    //update the property in advance
    //note: this approach will only work if toValue != nil
    [ CATransaction begin ];                                          //  ——— 1
    [CATransaction setDisableActions:YES];  
    layer.backgroundColor = (__bridge CGColorRef)(animation.toValue) ;
    [CATransaction commit];
   
   
//apply animation to layer
    [layer
addAnimation:animation forKey:nil];
}
- (IBAction)changeColor
{
   
//create a new random color
   
CGFloat red = arc4random() / (CGFloat)INT_MAX;
   
CGFloat green = arc4random() / (CGFloat)INT_MAX;
   
CGFloat blue = arc4random() / (CGFloat)INT_MAX;
   
UIColor *color = [UIColor colorWithRed:red
                                    
green:green
                                     
blue:blue
                                     alpha:1.0];
    //create a basic animation
   
CABasicAnimation *animation = [CABasicAnimation animation];
    animation.
keyPath = @"backgroundColor";
    animation.toValue = (__bridge id)color.CGColor;
    //apply animation without snap-back
    [
self applyBasicAnimation:animation toLayer:self.colorLayer];
}

CABasicAnimation 揭示了大多数隐式动画背后依赖的机制,这的确很有趣,但是显式地给图层添加 CABasicA nimation 相较于隐式动画而言,只能说费力不讨好。
CAKeyframeAnimation:关键帧动画 是另一种UIKit没有暴露出来但功能强大的类。和CABasicAnimation不同的是, 限制于设置一个起始和结束的值,而是可以根据一连串随意的值来做动画。

- (IBAction)changeColor
{   
   
//create a keyframe animation
   
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    animation.
keyPath = @"backgroundColor";
    animation.
duration = 5;
    animation.
values = @[
                         (
__bridge id)[UIColor blueColor].CGColor,
                         (
__bridge id)[UIColor redColor].CGColor,
                         (
__bridge id)[UIColor greenColor].CGColor,
                         (
__bridge id)[UIColor blueColor].CGColor
                        
];
   
   
//apply animation to layer
       [
self.colorLayer addAnimation:animation forKey:nil];
}


如代码所示,设置values属性值可以让CALayer按照设定的值做动画,但用数组来描述动画运动并不直观,设置path属性将会更加直观。虽然Core Graphics给我们提供绘制CGPath的方法,但是使用UIKit提供的UIBezierPath会更加方便。
- (void)viewDidLoad
{
    [super viewDidLoad];
    //create a path
   
UIBezierPath *bezierPath = [[UIBezierPath alloc] init];
    [bezierPath
moveToPoint:CGPointMake(0, 150)];
    [bezierPath
addCurveToPoint:CGPointMake(300, 150)
                 
controlPoint1:CGPointMake(75, 0)
                 
controlPoint2:CGPointMake(225, 300)];
   
   
//draw the path using a CAShapeLayer
   
CAShapeLayer *pathLayer = [CAShapeLayer layer];
    pathLayer.
path = bezierPath.CGPath;
    pathLayer.
fillColor = [UIColor clearColor].CGColor;
    pathLayer.
strokeColor = [UIColor redColor].CGColor;
    pathLayer.
lineWidth = 3.0f;
    [
self.containerView.layer addSublayer:pathLayer];
   
   
//add the ship------
   
CALayer *shipLayer = [CALayer layer];
    shipLayer.
frame = CGRectMake(0, 0, 64, 64);
    shipLayer.
position = CGPointMake(0, 150);
    shipLayer.
contents = (__bridge id)[UIImage imageNamed:@"Ship.png"].CGImage;
    [self.containerView.layer addSublayer:shipLayer];   
    //create the keyframe animation
   
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    animation.
keyPath = @"position";
    animation.
duration = 4.0;
    animation.
path = bezierPath.CGPath;
    [shipLayer
addAnimation:animation forKey:nil];
}



属性动画主要是作用于属性,介绍完属性动画CAPropertyAnimaition后。现在介绍动画组CAAnimationGroup,动画组主要是将几个动画组合在一起。
CAAnimationGroup类有一个animations属性。用法比较简单。

CAAnimation还有一个子类:CATransition 过渡动画。不是所有视图的属性都是动画属性,如果要改变不能动画的属性(如title,image...),或者添加移除图层,属性动画将起不到作用。这时候我们可以使用过渡动画。(例子在隐式动画中就有)






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值