美文网首页
【Objective-C】Animation动画

【Objective-C】Animation动画

作者: MR_詹 | 来源:发表于2020-11-26 10:10 被阅读0次

position 和 anchorPoint

都是CALayer的两个非常重要的属性

@proper CGPoinstposition
用来设置CALayer在父层中的位置
以父层的左上角为原点(0,0)

@proper CGPoinst anchorPoint
称为“定位点”、“锚点”
决定着CALayer身上的哪个点会再position属性使指的位置
以自己的左上角为原点(0,0)
它的x,y取值范围都是0~1,默认值为(0.5,0.5)

备注:实际上position点与anchorPoint点都是指向同一个点,只是相对的位置不一样,position点是相对父层的坐标系,而anchorPoint 是相对自己的坐标系,但是如果anchorPoint点的不同,显示的效果就不一样了,比如


image.png image.png

隐式动画

  • 每个UIView内部都默认关联一个CALayer,我么可称这个Layer为RootLayer(根层)
  • 所有的非RootLayer ,也就是手动创建的CALayer对象,都存在着隐式动画

当对非RootLayer的部分属性进行修改时,默认会自动产生一些动画效果
而这些属性称为Animation Properties(可动画属性)
常见的以下几种:
bounds:用于设置CALayer的宽度和高度,修改这个属性会产生缩放动画
backgrounds:用于设置CALayer的背景颜色,修改这个属性会产生背景颜色的渐变动画
position:用于设置CALayer的位置,修改这个属性会产生平移动画

备注:
设置隐式动画执行时间
// 比如设置隐式动画执行时间是2秒
[CATransaction setAnimationDuration:2];
// 执行要修改的可动画属性:比如位移
self.myView.layer.position = CGPoint(10,10)

// 关闭隐式动画 YES:表示关闭隐式动画   NO:开启隐式动画
// 只要是setDisableActions:YES之后的可动画属性设置了,是没有隐式动画
[CATransaction setDisableActions:YES];
self.myView.layer.position = CGPoint(10,10)

// 动画事务CATranscation
// 动画的设置只对begin 和 commit之间的设置有效
// 比如设置位移的时候有隐式动画,修改背景颜色的时候关闭隐式动画
CATransaction begin];
[CATransaction setDisableActions:YES];
// 执行要修改的可动画属性
self.myView.layer.position = CGPointMake(10, 10);
[CATransaction commit];
self.myView.layer.background = [UIColor red].CGColor; 

核心动画

Core Animation 核心动画
1>可以在Mac OS 和 iOS平台
2>Core Animation动画执行过程都是在后台操作的,不会柱塞主线程
3>Core Animation是直接作用在CALayer上的,并非UIView

image.png transform相关属性值

CABaseAnimation

心跳
#import "ViewController.h"

@interface ViewController ()
@property (nonatomic, strong, readwrite) UIImageView      *imageView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.imageView];
}


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    // 创建动画对象
    CABasicAnimation *animation = [CABasicAnimation animation];
    // 设置属性
    animation.keyPath = @"transform.scale";
    animation.toValue = @0;
    // 设置动画执行次数
    animation.repeatCount = MAXFLOAT;
    // 设置动画执行时间
    animation.duration = 1;
    // 自动反转(怎么样去,怎么样回来)
    animation.autoreverses = YES;
    
    [self.imageView.layer addAnimation:animation forKey:nil];
    
}

- (UIImageView *)imageView {
    if (!_imageView) {
        _imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"测试"]];
        _imageView.userInteractionEnabled = YES;
        _imageView.image = [UIImage imageNamed:@"timg-2"];
        _imageView.frame = CGRectMake(100, 100, 200, 200);
    }
    return _imageView;
}

@end

CAKeyframeAnimation

图片抖动
#import "ViewController.h"

#define angl2Rad(x)  ((x)*M_PI/180)

@interface ViewController ()
@property (nonatomic, strong, readwrite) UIImageView      *imageView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.imageView];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    // 创建动画对象
    CAKeyframeAnimation *animatino = [CAKeyframeAnimation animation];
    // 设置属性值
    animatino.keyPath = @"transform.rotation";
    animatino.values = @[@(angl2Rad(-3)),@(angl2Rad(3)),@(angl2Rad(-3))];
    // 设置动画执行次数
    animatino.repeatCount = MAXFLOAT;
    // 设置动画执行时间
    animatino.duration = 0.5;
    
    [self.imageView.layer addAnimation:animatino forKey:nil];
}

- (UIImageView *)imageView {
    if (!_imageView) {
        _imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"测试"]];
        _imageView.userInteractionEnabled = YES;
        _imageView.image = [UIImage imageNamed:@"timg-2"];
        _imageView.frame = CGRectMake(100, 100, 200, 200);
    }
    return _imageView;
}


@end
根据路径移动
#import "ViewController.h"

#define angl2Rad(x)  ((x)*M_PI/180)

@interface ViewController ()
@property (nonatomic, strong, readwrite) UIImageView      *imageView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.imageView];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    // 创建动画对象
    CAKeyframeAnimation *animatino = [CAKeyframeAnimation animation];
    
    // 创建路径:使图片按照路径移动
    UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRect:CGRectMake(50, 50, 200, 200)];
    
    // 设置属性值
    animatino.keyPath = @"position";
    animatino.path = bezierPath.CGPath;
    
    // 设置动画执行次数
    animatino.repeatCount = MAXFLOAT;
    // 设置动画执行时间
    animatino.duration = 5;
    
    [self.imageView.layer addAnimation:animatino forKey:nil];
}

- (UIImageView *)imageView {
    if (!_imageView) {
        _imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"测试"]];
        _imageView.userInteractionEnabled = YES;
        _imageView.image = [UIImage imageNamed:@"timg-2"];
        _imageView.frame = CGRectMake(100, 100, 200, 200);
    }
    return _imageView;
}
@end

转场动画

image.png 切换图片
@interface ViewController ()
@property (nonatomic, strong, readwrite) UIImageView      *imageView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.imageView];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    static NSInteger i = 1;
    I++;
    if (i==4) {
        I=1;
    }
    NSString *imageName = [NSString stringWithFormat:@"%ld",I];
    self.imageView.image = [UIImage imageNamed:imageName];
    // 创建动画对象
    CATransition *animation = [CATransition animation];
    // 设置转场动画的效果
    animation.type = @"pageUnCurl";
    animation.duration = 1;
    // 设置动画的起始位置
    animation.startProgress = 0.3;
    // 设置动画的结束位置
    animation.endProgress = 0.8;
    
    [self.imageView.layer addAnimation:animation forKey:nil];

  // 注意点:
  // 转场代码与转场动画必须得在同一个方法中
}

- (UIImageView *)imageView {
    if (!_imageView) {
        _imageView = [[UIImageView alloc]initWithFrame:self.view.bounds];
        _imageView.image = [UIImage imageNamed:@"1"];
        _imageView.userInteractionEnabled = YES;
    }
    return _imageView;
}
@end

动画组(同时执行多个动画)

图片向下移动的时候同时缩小
#import "ViewController.h"

@interface ViewController ()
@property (nonatomic, strong, readwrite) UIImageView      *imageView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.imageView];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    CABasicAnimation *animation1 = [CABasicAnimation animation];
    animation1.keyPath = @"position.y";
    animation1.toValue = @(400);
    
    CABasicAnimation *animation2 = [CABasicAnimation animation];
    animation2.keyPath = @"transform.scale";
    animation2.toValue = @(0.5);
    
    CAAnimationGroup *group = [CAAnimationGroup animation];
    group.animations = @[animation1,animation2];
    // 以下的设置都是对动画组内的所有动画都有效
    // 如果想每个动画的设置不一样,则在创建动画对象的时候单独设置
    // 动画执行时间
    group.duration = 1;
    // 动画结束后保持当前状态
    group.removedOnCompletion = NO;
    group.fillMode = kCAFillModeForwards;
    
    [self.imageView.layer addAnimation:group forKey:nil];
}

- (UIImageView *)imageView {
    if (!_imageView) {
        _imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
        _imageView.image = [UIImage imageNamed:@"1"];
        _imageView.userInteractionEnabled = YES;
    }
    return _imageView;
}

@end

UIView与核心动画的区别?

1. 核心动画只作用在Layer
2. 核心动画看到的都是假象,它并没有修改UIView的真实位置(只修改layer的显示,这回导致UIView显示的位置与手势的作用域不一样)

什么时候使用核心动画?
1. 当不需要与用户进行交互,使用核心动画
2.  当要根据路径做动画时,使用核心动画
3. 当做转场动画时,使用核心动画(核心动画转场类型比较多,当荣UIView也是能先做转场动画的)

相关文章

网友评论

      本文标题:【Objective-C】Animation动画

      本文链接:https://www.haomeiwen.com/subject/aebzvhtx.html