iOS frame动画

   在iOS 开发中,要做一个动画效果,我们会用到**CAKeyframeAnimation**。 

这个库提供了一些对frame 动画的控制。 与在CAKeyframeAnimation 的概念是一样, 你只需要提供keyframe 的信息, 程序会自动完成keyframe之间的”图画”。
例: 如果想对一个图形做一个弹出的动画, 用CAKeyframeAnimation可以写成

CAKeyframeAnimation *boundsOvershootAnimation = [CAKeyframeAnimation animationWithKeyPath:@"bounds.size"];
CGSize startingSize = CGSizeZero;
CGSize targetSize = CGSizeMake(100,100);
CGSize overshootSize = CGSizeMake(120,120);
CGSize undershootSize = CGSizeMake(80,80);

NSArray *boundsValues = [NSArray arrayWithObjects:[NSValue valueWithCGSize:startingSize],
       [NSValue valueWithCGSize:targetSize],
       [NSValue valueWithCGSize:overshootSize],
       [NSValue valueWithCGSize:undershootSize],
       [NSValue valueWithCGSize:targetSize], nil];
[boundsOvershootAnimation setValues:boundsValues];

NSArray *times = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0f],
  [NSNumber numberWithFloat:0.5f],
      [NSNumber numberWithFloat:0.8f],
      [NSNumber numberWithFloat:0.9f],
      [NSNumber numberWithFloat:1.0f], nil];    
[boundsOvershootAnimation setKeyTimes:times];
boundsOvershootAnimation.duration = 1.0;

这个弹出的动画包含了5个keyframe, 目的是令弹出带点跳动的感觉。 [boundsOvershootAnimation setValues:boundsValues] 这一行代码就设定了这动画的keyframe。 另一个重要的元素就是时间, CAKeyframeAnimation 提供了keyframe 时间的控制, 如果不设定便会以直线性发展。 而这动画会以先慢後快的形式出现, 为什麽呢? 请看[boundsOvershootAnimation setKeyTimes:times] 这一段。 动画长一秒, 由0-0.5秒会进行 startingSize 到 targetSize 的动画, 0.5-0.8秒会进行 targetSize 到 overshootSize 的动画。 如此类推就会做出先慢後快的效果。

例2,一个透明淡出的动画

CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
opacityAnimation.fromValue = [NSNumber numberWithFloat:1.0f]; 
opacityAnimation.toValue  = [NSNumber numberWithFloat:0.0f];
opacityAnimation.timingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]]; 
// EaseIn curve
//opacityAnimation.timingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]]; 
// EaseOut curve
//opacityAnimation.timingFunction = [CAMediaTimingFunction functionWithControlPoints:1.0 :0.0 :1.0 :0.1]; 
// Bezier curve

opacityAnimation.timingFunction 是用来控制动画线性发展。 其中[CAMediaTimingFunction functionWithControlPoints:1.0 :0.0 :1.0 :0.1] 是一个贝塞尔曲线的控制方法。 这也可以令动画做到先慢後快或先快後慢的结果。

例3,皮球跳动的效果

EasingFunction easingFn = [Easing getBounce];
CAKeyframeAnimation *transAnimi = [CAKeyframeAnimation animationWithKeyPath:@"position.x" easeFunction:easingFn.easeOut fromValue:0.0 toValue:200];
transAnimi.duration = 3.0;

[Easing getBounce] 是Tween动画库内跳动效果的公式。 [CAKeyframeAnimation animationWithKeyPath:@”position.x” easeFunction:easingFn.easeOut fromValue:0.0 toValue:200]是CAKeyframeAnimation的扩展。 回传的是一般CAKeyframeAnimation, 可以直接用在UIView 物件上。

一,速度控制函数(CAMediaTimingFunction)

1》.kCAMediaTimingFunctionLinear(线性):匀速,给你一个相对静态的感觉
2》.kCAMediaTimingFunctionEaseIn(渐进):动画缓慢进入,然后加速离开
3》.kCAMediaTimingFunctionEaseOut(渐出):动画全速进入,然后减速的到达目的地
4》.kCAMediaTimingFunctionEaseInEaseOut(渐进渐出):动画缓慢的进入,中间加速,然后减速的到达目的地。这个是默认的动画行为。

CAAnimation在分类中定义了代理方法

@interfaceNSObject (CAAnimationDelegate)
-(void)animationDidStart:(CAAnimation )anim;
-(void)animationDidStop:(CAAnimation )anim finished:(BOOL)flag;
@end

pragmamark 暂停CALayer的动画

-(void)pauseLayer:(CALayer*)layer
{
CFTimeInterval pausedTime = [layerconvertTime:CACurrentMediaTime() fromLayer:nil];
layer.speed=0.0; // 让CALayer的时间停止走动
layer.timeOffset=pausedTime; // 让CALayer的时间停留在pausedTime这个时刻
}

pragmamark 恢复CALayer的动画

-(void)resumeLayer:(CALayer*)layer
{
CFTimeInterval pausedTime =layer.timeOffset;
layer.speed=1.0; // 让CALayer的时间继续行走
layer.timeOffset=0.0; // 取消上次记录的停留时刻
layer.beginTime=0.0; // 取消上次设置的时间

//计算暂停的时间(这里用CACurrentMediaTime()-pausedTime也是一样的)
CFTimeInterval timeSincePause = [layerconvertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
//设置相对于父坐标系的开始时间(往后退timeSincePause)
layer.beginTime = timeSincePause;
}

二,Tween动画库是可以再扩展。参考下列直线性的公式, t是当前时间值, b是属性开始值, c是属性变化差, d是总时间值, 回传的是t时间的属性值。大家可以自由改变去创建一个新的公式。

+(EasingFunction)getLinear{
    EasingFunction ease;
    ease.easeIn = ^double(double t, double b, double c, double d) {
        return c*t/d + b;
    };
    ease.easeOut = ^double(double t, double b, double c, double d) {
        return c*t/d + b;
    };
    ease.easeInOut = ^double(double t, double b, double c, double d) {
  return c*t/d + b;
    };
    return ease;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值