zoukankan      html  css  js  c++  java
  • iOS 动画基础-显式动画

    摘要

    显式动画

        属性动画

    CABasicAnimation *animation = [CABasicAnimation animation];
            [self updateHandsAnimated:NO];
            animation.keyPath = @"transform";
            animation.toValue = [NSValue valueWithCATransform3D:transform];
            animation.duration = 0.5;
            animation.delegate = self;
            [animation setValue:handView forKey:@"handView"];

        关键帧动画

        CAKeyframeAnimation是另一种UIKit没有暴露出来但功能强大的类。和CABasicAnimation类似,CAKeyframeAnimation同样是CAPropertyAnimation的一个子类,它依然作用于单一的一个属性,但是和CABasicAnimation不一样的是,它不限制于设置一个起始和结束的值,而是可以根据一连串随意的值来做动画。

        关键帧起源于传动动画,意思是指主导的动画在显著改变发生时重绘当前帧(也就是关键帧),每帧之间剩下的绘制(可以通过关键帧推算出)将由熟练的艺术家来完成。CAKeyframeAnimation也是同样的道理:你提供了显著的帧,然后Core Animation在每帧之间进行插入。

    - (IBAction)changeColor
    {
        //create a keyframe animation
        CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
        animation.keyPath = @"backgroundColor";
        animation.duration = 2.0;
        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];
    }

        动画组

        CABasicAnimation和CAKeyframeAnimation仅仅作用于单独的属性,而CAAnimationGroup可以把这些动画组合在一起。CAAnimationGroup是另一个继承于CAAnimation的子类,它添加了一个animations数组的属性,用来组合别的动画。

        

    - (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 a colored layer
        CALayer *colorLayer = [CALayer layer];
        colorLayer.frame = CGRectMake(0, 0, 64, 64);
        colorLayer.position = CGPointMake(0, 150);
        colorLayer.backgroundColor = [UIColor greenColor].CGColor;
        [self.containerView.layer addSublayer:colorLayer];
        //create the position animation
        CAKeyframeAnimation *animation1 = [CAKeyframeAnimation animation];
        animation1.keyPath = @"position";
        animation1.path = bezierPath.CGPath;
        animation1.rotationMode = kCAAnimationRotateAuto;
        //create the color animation
        CABasicAnimation *animation2 = [CABasicAnimation animation];
        animation2.keyPath = @"backgroundColor";
        animation2.toValue = (__bridge id)[UIColor redColor].CGColor;
        //create group animation
        CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
        groupAnimation.animations = @[animation1, animation2]; 
        groupAnimation.duration = 4.0;
        //add the animation to the color layer
        [colorLayer addAnimation:groupAnimation forKey:nil];
    }

        

        过渡

        有时候对于iOS应用程序来说,希望能通过属性动画来对比较难做动画的布局进行一些改变。比如交换一段文本和图片,或者用一段网格视图来替换,等等。属性动画只对图层的可动画属性起作用,所以如果要改变一个不能动画的属性(比如图片),或者从层级关系中添加或者移除图层,属性动画将不起作用。

        于是就有了过渡的概念。过渡并不像属性动画那样平滑地在两个值之间做动画,而是影响到整个图层的变化。过渡动画首    先展示之前的图层外观,然后通过一个交换过渡到新的外观。

        为了创建一个过渡动画,我们将使用CATransition,同样是另一个CAAnimation的子类,和别的子类不同,CATransition有一个type和subtype来标识变换效果。type属性是一个NSString类型,可以被设置成如下类型:

    kCATransitionFade 
    kCATransitionMoveIn 
    kCATransitionPush 
    kCATransitionReveal

    到目前为止你只能使用上述四种类型,但你可以通过一些别的方法来自定义过渡效果,默认的过渡类型是kCATransitionFade,当你在改变图层属性之后,就创建了一个平滑的淡入淡出效果。kCATransitionPush,它创建了一个新的图层,从边缘的一侧滑动进来,把旧图层从另一侧推出去的效果。

    kCATransitionMoveIn和kCATransitionReveal与kCATransitionPush类似,都实现了一个定向滑动的动画,但是有一些细微的不同,kCATransitionMoveIn从顶部滑动进入,但不像推送动画那样把老土层推走,然而kCATransitionReveal把原始的图层滑动出去来显示新的外观,而不是把新的图层滑动进入。

    后面三种过渡类型都有一个默认的动画方向,它们都从左侧滑入,但是你可以通过subtype来控制它们的方向,提供了如下四种类型:

    kCATransitionFromRight 

    kCATransitionFromLeft 

    kCATransitionFromTop 

    kCATransitionFromBottom

    @interface ViewController ()
    
    @property (nonatomic, weak) IBOutlet UIImageView *imageView;
    @property (nonatomic, copy) NSArray *images;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        //set up images
        self.images = @[[UIImage imageNamed:@"Anchor.png"],
                        [UIImage imageNamed:@"Cone.png"],
                        [UIImage imageNamed:@"Igloo.png"],
                        [UIImage imageNamed:@"Spaceship.png"]];
    }
    
    
    - (IBAction)switchImage
    {
        //set up crossfade transition
        CATransition *transition = [CATransition animation];
        transition.type = kCATransitionFade;
        //apply transition to imageview backing layer
        [self.imageView.layer addAnimation:transition forKey:nil];
        //cycle to next image
        UIImage *currentImage = self.imageView.image;
        NSUInteger index = [self.images indexOfObject:currentImage];
        index = (index + 1) % [self.images count];
        self.imageView.image = self.images[index];
    }
    
    @end

        你可以从代码中看出,过渡动画和之前的属性动画或者动画组添加到图层上的方式一致,都是通过-addAnimation:forKey:方法。但是和属性动画不同的是,对指定的图层一次只能使用一次CATransition,因此,无论你对动画的键设置什么值,过渡动画都会对它的键设置成“transition”,也就是常量kCATransition。

        自定义动画

    苹果通过UIView +transitionFromView:toView:duration:options:completion:和+transitionWithView:duration:options:animations:方法提供了Core Animation的过渡特性。但是这里的可用的过渡选项和CATransition的type属性提供的常量完全不同。UIView过渡方法中options参数可以由如下常量指定:

    UIViewAnimationOptionTransitionFlipFromLeft 

        使用UIKit提供的方法来做过渡动画

    @interface ViewController ()
    @property (nonatomic, weak) IBOutlet UIImageView *imageView;
    @property (nonatomic, copy) NSArray *images;
    @end
    @implementation ViewController
    - (void)viewDidLoad
    {
        [super viewDidLoad]; //set up images
        self.images = @[[UIImage imageNamed:@"Anchor.png"],
                        [UIImage imageNamed:@"Cone.png"],
                        [UIImage imageNamed:@"Igloo.png"],
                        [UIImage imageNamed:@"Spaceship.png"]];
    - (IBAction)switchImage
    {
        [UIView transitionWithView:self.imageView duration:1.0
                           options:UIViewAnimationOptionTransitionFlipFromLeft
                        animations:^{
                            //cycle to next image
                            UIImage *currentImage = self.imageView.image;
                            NSUInteger index = [self.images indexOfObject:currentImage];
                            index = (index + 1) % [self.images count];
                            self.imageView.image = self.images[index];
                        }
                        completion:NULL];
    }
    
    @end

     

  • 相关阅读:
    UVA 1025 A Spy in the Metro DP水题
    ZOJ 3814 Sawtooth Puzzle BFS
    ZOJ 3816 Generalized Palindromic Number
    UVA 10859 Placing Lampposts 树形DP
    UVA 11825 Hackers' Crackdown 状压DP
    POJ 2887 Big String 线段树 离线处理
    POJ 1635 Subway tree systems Hash法判断有根树是否同构
    BZOJ 3110 k大数查询 & 树套树
    sdoi 2009 & 状态压缩
    来自于2016.2.24的flag
  • 原文地址:https://www.cnblogs.com/baitongtong/p/5853120.html
Copyright © 2011-2022 走看看