iOS面试

iOS Core Animation

2021-11-19  本文已影响0人  搬砖的crystal

一、Core Animation 类简介

Core Animation是 iOS 和 OS X 平台上负责图形渲染与动画的基础框架。Core Animation 可以作用于动画视图或者其他可视元素,可以完成动画所需的大部分绘帧工作。Core Animation 系统已经进行了封装,所以在使用的时候你只需要配置少量的动画参数(如开始点的位置和结束点的位置)即可使用 Core Animation 的多种动画效果。Core Animation 将大部分实际的绘图任务交给了图形硬件(GPU)来处理,图形硬件会加速图形渲染的速度。这种自动化的图形加速技术让动画拥有更高的帧率并且显示效果更加平滑,不会加重CPU的负担而影响程序的运行速度。

Core Animation 的动画执行过程都是在后台操作的,不会阻塞主线程。
要注意的是,Core Animation 是直接作用在 CALayer 上的,并非 UIView

黑线代表继承,黑色文字代表类名,白色文字代表属性。其中 CAMediaTiming 是一个协议(protocol)。

CAAnimation是所有动画类的父类,但是它不能直接使用,应该使用它的子类
CAPropertyAnimation 也是不能直接使用的,也要使用它的子类
能用的动画类只剩下4个:CABasicAnimationCAKeyframeAnimation``、CATransitionCAAnimationGroup`。

动画的各个属性及作用
1、fromValue

动画的开始值(Any类型, 根据动画不同可以是CGPointNSNumber 等)

2、toValue

动画的结束值,和 fromValue 类似

3、beginTime

动画的开始时间

4、duration

动画的持续时间

5、repeatCount

动画的重复次数

6、fillMode

动画的运行场景

7、isRemovedOnCompletion

完成后是否删除动画

8、autoreverses

执行的动画按照原动画返回执行

9、path

关键帧动画中的执行路径

10、values

关键帧动画中的关键点数组

11、animations

组动画中的动画数组

12、delegate

动画代理, 封装了动画的执行和结束方法

13、timingFunction

控制动画的显示节奏,系统提供五种值选择,分别是

14、type

过渡动画的动画类型,系统提供了多种过渡动画,分别是

15、subtype

过渡动画的动画方向,系统提供了四种,分别是

二、基础动画CABasicAnimation

基础动画主要提供了对于 CALayer 对象中的可变属性进行简单动画的操作。比如:位移、旋转、缩放、透明度、背景色等。

基础动画根据 keyPath 来区分不同的动画,系统提供了多个类型,如:transform.scale 比例转换、transform.scale.xtransform.scale.ytransform.rotation旋转 、transform.rotation.x绕x轴旋转、transform.rotation.y绕y轴旋转、transform.rotation.z绕z轴旋转、opacity 透明度、marginbackgroundColor背景色、cornerRadius圆角、borderWidth边框宽、boundscontentscontentsRectcornerRadiusframehiddenmaskmasksToBoundsshadowColor阴影色、shadowOffsetshadowOpacityshadowOpacity,在使用时候, 需要根据具体的需求选择合适的。

//
//  ViewController.m
//  DJTestTwo
//
//  Created by admin on 2021/11/10.
//

#import "ViewController.h"

@interface ViewController ()
@property(nonatomic,strong)UIView *viewA;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.viewA];
    [self backgroundColorAnimation];
}
//位移动画
- (void)positionAnimaton{
    CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"position"];
    animation.toValue = [NSValue valueWithCGPoint:CGPointMake(300, 100)];//动画要去的点
    animation.duration = 2.0;//时间
    [self.viewA.layer addAnimation:animation forKey:@"positionAnimaton"];//添加动画自定义的标识
}
//旋转动画
- (void)rotateAnimation{
    CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    animation.toValue = [NSNumber numberWithDouble:M_PI];
    animation.duration = 2.0;//时间
    animation.repeatCount = 1e100;//无限大重复次数
    [self.viewA.layer addAnimation:animation forKey:@"rotateAnimation"];
}
//缩放动画
- (void)scaleAnimation{
    CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    animation.toValue = [NSNumber numberWithInt:2];
    animation.duration = 2.0;
    animation.repeatCount = 1e100;
    [self.viewA.layer addAnimation:animation forKey:@"scaleAnimation"];
}
//透明度动画
- (void)opacityAnimation{
    CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
    animation.fromValue = [NSNumber numberWithInt:1];
    animation.toValue = [NSNumber numberWithInt:0];
    animation.duration = 2.0;
    animation.repeatCount = 1e100;
    [self.viewA.layer addAnimation:animation forKey:@"opacityAnimation"];
}
//背景色动画
- (void)backgroundColorAnimation{
    CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
    animation.toValue = (id)[UIColor greenColor].CGColor;
    animation.duration = 2.0;
    animation.repeatCount = 1e100;
    [self.viewA.layer addAnimation:animation forKey:@"backgroundColorAnimation"];
}

-(UIView *)viewA{
    if (!_viewA) {
        _viewA = [[UIView alloc]initWithFrame:CGRectMake(10, 70, 100, 100)];
        _viewA.backgroundColor = [UIColor yellowColor];
    }
    return _viewA;
}

@end

三、关键帧动画 CAKeyframeAnimation

CAKeyframeAnimationCABasicAnimation 都属于 CAPropertyAnimatin 的子类。不同的是 CABasicAnimation 只能从一个数值(fromValue)变换成另一个数值(toValue),而 CAKeyframeAnimation 则会使用一个数组(values) 保存一组关键帧,也可以给定一个路径(path)制作动画。

CAKeyframeAnimation 主要有 三个 重要属性:

//
//  ViewController.m
//  DJTestTwo
//
//  Created by admin on 2021/11/10.
//

#import "ViewController.h"

@interface ViewController ()
@property(nonatomic,strong)UIView *viewA;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.viewA];
    [self shakeAnimation];
}
//关键帧动画
- (void)keyFrameAnimation{
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    animation.keyPath = @"position";
    NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
    NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(200, 100)];
    NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(200, 200)];
    NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(100, 200)];
    NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
    animation.values = @[value1,value2,value3,value4,value5];
    animation.repeatCount = MAXFLOAT;
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    animation.duration = 4.0f;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.viewA.layer addAnimation:animation forKey:@"keyFrameAnimation"];
}
//路径动画
- (void)pathAnimation{
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    animation.keyPath = @"position";
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddEllipseInRect(path, NULL, CGRectMake(150, 100, 100, 100));
    animation.path = path;
    CGPathRelease(path);
    animation.repeatCount = MAXFLOAT;
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    animation.duration = 4.0f;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.viewA.layer addAnimation:animation forKey:@"pathAnimation"];
}
//抖动动画
- (void)shakeAnimation{
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    animation.keyPath = @"transform.rotation";
    NSValue *value1 = [NSNumber numberWithDouble:M_PI/180*8];
    NSValue *value2 = [NSNumber numberWithDouble:-M_PI/180*8];
    animation.values = @[value1,value2];
    animation.repeatCount = MAXFLOAT;
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    animation.duration = 1.0f;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.viewA.layer addAnimation:animation forKey:@"shakeAnimation"];
}

-(UIView *)viewA{
    if (!_viewA) {
        _viewA = [[UIView alloc]initWithFrame:CGRectMake(10, 70, 100, 100)];
        _viewA.backgroundColor = [UIColor yellowColor];
    }
    return _viewA;
}

@end

四、组动画 CAAnimationGroup

CAAnimationGroupCAAnimation 的子类,可以保存一组动画对象,可以保存基础动画、关键帧动画等,数组中所有动画对象可以同时并发运行,也可以通过实践设置为串行连续动画。

//
//  ViewController.m
//  DJTestTwo
//
//  Created by admin on 2021/11/10.
//

#import "ViewController.h"

@interface ViewController ()
@property(nonatomic,strong)UIView *viewA;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.viewA];
    [self groupAnimation];
}
- (void)groupAnimation{
    CAAnimationGroup *group = [CAAnimationGroup animation];
    CABasicAnimation *anim = [CABasicAnimation animation];
    anim.keyPath = @"position";
    anim.toValue = [NSValue valueWithCGPoint:CGPointMake(arc4random_uniform(200), arc4random_uniform(500))];
    // 缩放
    CABasicAnimation *anim1 = [CABasicAnimation animation];
    anim1.keyPath = @"transform.scale";
    // 0 ~ 1
    static CGFloat scale = 0.1;
    if (scale < 1) {
        scale = 1.5;
    }else{
        scale = 0.2;
    }
    anim1.toValue = @(scale);
    // 旋转
    CABasicAnimation *anim2 = [CABasicAnimation animation];
    anim2.keyPath = @"transform.rotation";
    anim2.toValue = @(arc4random_uniform(360) / 180.0 * M_PI);
    group.animations = @[anim,anim1,anim2];
    group.duration = 0.5;
    // 取消反弹
    // 告诉在动画结束的时候不要移除
    group.removedOnCompletion = NO;
    // 始终保持最新的效果
    group.fillMode = kCAFillModeForwards;
    [self.viewA.layer addAnimation:group forKey:nil];
}

-(UIView *)viewA{
    if (!_viewA) {
        _viewA = [[UIView alloc]initWithFrame:CGRectMake(10, 70, 100, 100)];
        _viewA.backgroundColor = [UIColor yellowColor];
    }
    return _viewA;
}

@end

五、过渡动画 CATransition

CATransitionCAAnimation 的子类,用于做过渡动画或者转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。

过渡动画通过 type 设置不同的动画效果,CATransition 有多种过渡效果,但其实 Apple 官方的SDK只提供了四种:

上一篇 下一篇

猜你喜欢

热点阅读