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

     

  • 相关阅读:
    宁波工程学院2020新生校赛C
    宁波工程学院2020新生校赛B
    宁波工程学院2020新生校赛A -恭喜小梁成为了宝可梦训练家~(水题)
    POJ 1611
    牛客算法周周练11E
    牛客算法周周练11C
    牛客算法周周练11A
    CodeForces 1176C
    CodeForces 445B
    UVALive 3027
  • 原文地址:https://www.cnblogs.com/baitongtong/p/5853120.html
Copyright © 2011-2022 走看看