第六篇:UIView block动画

2018-01-19  本文已影响149人  意一ineyee

在开始学习Core Animation提供的layer的隐式动画和layer的显式动画之前,我们先来总结一下UIView block动画,因为:


目录

一、UIView可动画属性列表

二、什么是UIView block动画?

1、UIView block动画的定义、本质及能做什么动画
2、UIView block动画的分类
(1)UIView block基础动画(UIView block属性动画的一种)
(2)UIView block关键帧动画(UIView block属性动画的一种)
(3)UIView block过渡动画

三、如何使用UIView block动画?(应用举例)

1、UIView block基础动画举例
2、UIView block关键帧动画举例
3、UIView block过渡动画举例

一、UIView可动画属性列表

最普通的属性 说明
backgroundColor --
frame 改位置和大小,一般使用transform的平移和缩放来代替
bounds 改大小,一般使用transform的缩放来代替
center 改位置,一般使用transform的平移来代替
显隐性属性 说明
hidden 注意这个属性不支持动画,最简单的可以通过alpha或背景色来代替实现
alpha --
仿射变换属性 说明
transform 可用来做view的平移、缩放、旋转动画

二、什么是UIView block动画?

1、UIView block动画的定义、本质及能做什么动画
2、UIView block动画的分类

UIView block动画可分为UIView block属性动画和UIView block过渡动画,而UIView block属性动画又可分为UIView block基础动画和UIView block关键帧动画,接下来我们将分别介绍UIView block基础动画UIView block关键帧动画UIView block过渡动画

(1)UIView block基础动画
①什么是UIView block基础动画?

UIView block基础动画是UIView block属性动画的一种,它用来对view的可动画属性做动画,但是执行一次UIView block基础动画只能改变一个属性值一次,因为我们是一次性把属性值直接设置为目标值的(如果要想改变多次属性的值,可以在动画结束后再开始一个基础动画再改一次属性值,如此循环,但有一个更简单的办法就是使用UIView block关键帧动画,后面会说到)它主要分下面四种:

[UIView animateWithDuration:// 动画时长
                 animations:^{
                     
                     // 要改变的属性
                 }];
[UIView animateWithDuration:// 动画时长
                 animations:^{
                     
                     // 要改变的属性
                 } completion:^(BOOL finished) {
                     
                     // 动画完成的回调
                 }];
[UIView animateWithDuration:// 动画时长
                      delay:// 延时多长时间后开始执行动画
                    options:// 可自定义动画的过渡效果,来替换掉系统默认的平滑过渡效果
                 animations:^{
                     
                     // 要改变的属性
                 } completion:^(BOOL finished) {
                     
                     // 动画完成的回调
                 }];

UIView block基础动画自定义过渡效果(UIViewAnimationOptions)枚举值如下:

UIViewAnimationOptionTransitionNone// 过渡动画效果:不使用过渡动画
UIViewAnimationOptionTransitionCrossDissolve//过渡动画效果:淡入淡出效果,和显示动画的过渡动画的“fade”一样
UIViewAnimationOptionTransitionFlipFromTop// 过渡动画效果:正面和背面的二维翻转效果,从上向下翻转
UIViewAnimationOptionTransitionFlipFromLeft// 过渡动画效果:正面和背面的二维翻转效果,从左向右翻转
UIViewAnimationOptionTransitionFlipFromBottom// 过渡动画效果:正面和背面的二维翻转效果,从下向上翻转
UIViewAnimationOptionTransitionFlipFromRight//过渡动画效果:正面和背面的二维翻转效果,从右向左翻转
UIViewAnimationOptionTransitionCurlUp// 过渡动画效果:翻页效果,从下往上翻页
UIViewAnimationOptionTransitionCurlDown// 过渡动画效果:翻页效果,从上往下翻页

UIViewAnimationOptionCurveEaseInOut// 过渡动画的缓冲曲线:动画慢进,逐渐加快,逐渐减慢,慢出(默认值)
UIViewAnimationOptionCurveEaseIn// 过渡动画的缓冲曲线:动画慢进,逐渐加快
UIViewAnimationOptionCurveEaseOut// 过渡动画的缓冲曲线:动画逐渐减慢,慢出
UIViewAnimationOptionCurveLinear// 过渡动画的缓冲曲线:动画匀速

UIViewAnimationOptionRepeat// 重复执行动画
UIViewAnimationOptionAllowUserInteraction// 执行动画期间,开启view的用户交互

UIViewAnimationOptionAutoreverse// 执行动画回路
UIViewAnimationOptionLayoutSubviews// 执行动画时布局子控件
UIViewAnimationOptionAllowAnimatedContent// 执行动画时重绘视图
UIViewAnimationOptionBeginFromCurrentState// 从当前状态开始执行动画
UIViewAnimationOptionShowHideTransitionViews// 显示视图时显示或隐藏而不是移除或添加
UIViewAnimationOptionOverrideInheritedOptions// 不继承父动画设置
UIViewAnimationOptionOverrideInheritedCurve// 忽略嵌套动画的曲线设置
UIViewAnimationOptionOverrideInheritedDuration// 忽略嵌套动画的执行时间设置
[UIView animateWithDuration:// 动画时长
                      delay:// 延时多长时间后开始执行动画
     usingSpringWithDamping:// 弹性效果的阻尼:范围0~1,数值越小弹性效果越明显,震得越久才能停下来
      initialSpringVelocity:// 弹性效果的初始速度:数值越大开始弹性动画时初始速度越快
                    options:// 可自定义动画的过渡效果,来替换掉系统默认的平滑过渡效果
                 animations:^{
                     
                     // 要改变的属性
                 } completion:^(BOOL finished) {
                     
                     // 动画完成的回调
                 }];
②如何使用UIView block基础动画?

我们只需要在UIView block基础动画的animationsblock里直接把可动画属性改变为目标值就可以了。

(2)UIView block关键帧动画
①什么是UIView block关键帧动画?

上面说到了UIView block基础动画是UIView block属性动画的一种,而此处的UIView block关键帧动画也是UIView block属性动画的一种,它也是用来对view的可动画属性做动画的,只不过效果可能在某些场景下比基础动画要方便或者丰富一些,但是执行一次UIView block关键帧动画可以设置多个关键帧所以能改变一个属性值多次,而不是一次性把属性值设置目标值

需要注意的是:UIView block关键帧动画设置关键帧只能通过增加关键帧方法来设置,相当于layer显示动画的关键帧动画的数组关键帧法,这个是不支持路径关键帧法的。

[UIView animateKeyframesWithDuration:// 动画时长
                               delay:// 延时多长时间后开始执行动画
                             options:// 可自定义动画的过渡效果,来替换掉系统默认的平滑过渡效果
                          animations:^{
                              
                              // 添加关键帧
                          } completion:^(BOOL finished) {
                              
                              // 动画完成的回调
                          }];

UIView block关键帧自定义过渡效果(UIViewKeyframeAnimationOptions)枚举值如下:

UIViewKeyframeAnimationOptionCalculationModeLinear// 运算模式:连续,默认
UIViewKeyframeAnimationOptionCalculationModeDiscrete// 运算模式:离散
UIViewKeyframeAnimationOptionCalculationModePaced// 运算模式:均匀执行
UIViewKeyframeAnimationOptionCalculationModeCubic// 运算模式:平滑
UIViewKeyframeAnimationOptionCalculationModeCubicPaced// 运算模式:平滑均匀

UIViewKeyframeAnimationOptionRepeat = UIViewAnimationOptionRepeat// 重复执行动画
UIViewKeyframeAnimationOptionAllowUserInteraction = UIViewAnimationOptionAllowUserInteraction// 执行动画期间,开启view的用户交互

UIViewKeyframeAnimationOptionAutoreverse = UIViewAnimationOptionAutoreverse// 执行动画回路
UIViewKeyframeAnimationOptionLayoutSubviews = UIViewAnimationOptionLayoutSubviews// 执行动画时布局子控件
UIViewKeyframeAnimationOptionBeginFromCurrentState = UIViewAnimationOptionBeginFromCurrentState// 从当前状态开始执行动画
UIViewKeyframeAnimationOptionOverrideInheritedOptions  = UIViewAnimationOptionOverrideInheritedOptions// 不继承父动画设置
UIViewKeyframeAnimationOptionOverrideInheritedDuration = UIViewAnimationOptionOverrideInheritedDuration// 忽略嵌套动画的执行时间设置
[UIView addKeyframeWithRelativeStartTime:// 这一帧动画开始的时间点(占总时间的比例)
                        relativeDuration:// 这一帧动画的动画时长(占总时间的比例)
                              animations:^{
                                  
                                  // 要改变的属性
                              }];
②如何使用UIView block关键帧动画?

我们只需要在UIView block关键帧动画的animationsblock里直接增加关键帧就可以了,再在增加关键帧方法的animationsblock里把可动画属性改变为目标值就可以了。

(3)UIView block过渡动画
①什么是UIView block过渡动画?

前面我们学习了UIView block基础动画和UIView block关键帧动画,但我们知道它俩其实都是UIView block属性动画,即只能用来对view的可动画属性做动画。那么如果我们现在想要对view的非动画属性改变时(如label的文本,imageView的图片等)做动画,甚至是对view的某些行为(如view的添加和移除,两个view之间切换)做动画,那就只能使用过渡动画了。

同时我们也可以看到,上面UIView block基础动画和UIView block关键帧动画的某些方法里也提供了过渡效果那个配置,也就是说过渡动画也是可以作用于可动画属性的,但是还可以做可动画属性之外的很多效果。

过渡动画的过渡效果可参见UIView block基础动画的过渡效果,是一模一样的。

[UIView transitionWithView:// 要做动画的视图
                  duration:// 动画时长
                   options:// 过渡动画效果
                animations:^{
                    
                    // 要改变的不可动画属性或图层行为
                } completion:^(BOOL finished) {
                    
                    // 动画完成的回调
                }];

注意:

[UIView transitionFromView:// 旧视图
                    toView:// 新视图
                  duration:// 动画时长
                   options:// 动画过渡效果
                completion:^(BOOL finished) {
                    
                    // 动画完成时的回调
                }];
②如何使用UIView block过渡动画?

我们只需要根据场景是改变单个视图的不可动画属性或视图行为要添加过渡动画还是给两个视图切换时添加过渡动画选择相应的方法就可以了。

三、UIView的block动画应用举例

1、UIView block基础动画
//
//  ViewController.m
//  CoreAnimation
//
//  Created by 意一yiyi on 2017/11/13.
//  Copyright © 2017年 意一yiyi. All rights reserved.
//

#import "ViewController.h"

#define kScreenWidth [UIScreen mainScreen].bounds.size.width
#define kScreenHeight [UIScreen mainScreen].bounds.size.height

@interface ViewController ()

@property (strong, nonatomic) UILabel *label;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.label = [[UILabel alloc] init];
    self.label.backgroundColor = [UIColor magentaColor];
    self.label.frame = CGRectMake(kScreenWidth, 100, kScreenWidth, 30);
    self.label.text = @"嘿Siri,你在哪儿?";
    [self.view addSubview:self.label];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    [UIView animateWithDuration:5 animations:^{
        
        self.label.transform = CGAffineTransformMakeTranslation(-kScreenWidth, 0);
    }];
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    [UIView animateWithDuration:5 animations:^{
        
        self.label.transform = CGAffineTransformMakeTranslation(-kScreenWidth, 0);
    } completion:^(BOOL finished) {
        
        self.label.text = @"你在哪儿,我就在哪儿!";
    }];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    [UIView animateWithDuration:3 delay:0 options:(UIViewAnimationOptionCurveLinear) animations:^{
        
        self.label.transform = CGAffineTransformMakeTranslation(-kScreenWidth, 0);
    } completion:^(BOOL finished) {
        
        self.label.text = @"你在哪儿,我就在哪儿!";
    }];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    [UIView animateWithDuration:3 delay:0 usingSpringWithDamping:0.2 initialSpringVelocity:5 options:(UIViewAnimationOptionCurveLinear) animations:^{
        
        self.label.transform = CGAffineTransformMakeTranslation(-kScreenWidth, 0);
    } completion:^(BOOL finished) {
        
        self.label.text = @"你在哪儿,我就在哪儿!";
    }];
}
1.gif
2、UIView block关键帧动画

类似FaceBook登录界面,登录失败那种输入框抖动的效果。要是使用基础动画的话,可能就得平移一次,再开一个基础动画再平移一次,得开好几个基础动画,关键帧动画的话就开一个动画就可以了,添关键帧就行了。

(清单1.5)

//
//  ViewController.m
//  CoreAnimation
//
//  Created by 意一yiyi on 2017/11/13.
//  Copyright © 2017年 意一yiyi. All rights reserved.
//

#import "ViewController.h"

#define kScreenWidth [UIScreen mainScreen].bounds.size.width
#define kScreenHeight [UIScreen mainScreen].bounds.size.height

@interface ViewController ()

@property (strong, nonatomic) UILabel *label;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.label = [[UILabel alloc] init];
    self.label.backgroundColor = [UIColor cyanColor];
    self.label.frame = CGRectMake(0, 100, kScreenWidth, 30);
    self.label.text = @"请登录";
    [self.view addSubview:self.label];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    self.label.text = @"登录失败";
    
    [UIView animateKeyframesWithDuration:0.5 delay:0 options:(UIViewKeyframeAnimationOptionCalculationModePaced) animations:^{
        
        [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:1/4.0 animations:^{
            
            self.label.transform = CGAffineTransformMakeTranslation(10, 0);
        }];
        [UIView addKeyframeWithRelativeStartTime:1/4.0 relativeDuration:1/4.0 animations:^{
            
            self.label.transform = CGAffineTransformMakeTranslation(-10, 0);
        }];
        [UIView addKeyframeWithRelativeStartTime:2/4.0 relativeDuration:1/4.0 animations:^{
            
            self.label.transform = CGAffineTransformMakeTranslation(10, 0);
        }];
        [UIView addKeyframeWithRelativeStartTime:3/4.0 relativeDuration:1/4.0 animations:^{
            
            self.label.transform = CGAffineTransformMakeTranslation(0, 0);
        }];
    } completion:^(BOOL finished) {
        
        NSLog(@"动画结束了");
    }];
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
1.gif
3、UIView block过渡动画
(1)给单个视图的不可动画属性或视图行为添加过渡动画

(清单1.6)

//
//  ViewController.m
//  CoreAnimation
//
//  Created by 意一yiyi on 2017/11/13.
//  Copyright © 2017年 意一yiyi. All rights reserved.
//

#import "ViewController.h"

#define kScreenWidth [UIScreen mainScreen].bounds.size.width
#define kScreenHeight [UIScreen mainScreen].bounds.size.height

@interface ViewController ()

@property (strong, nonatomic) UIImageView *imageView;
@property (strong, nonatomic) UILabel *label;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.imageView = [[UIImageView alloc] init];
    self.imageView.frame = CGRectMake(0, 64, kScreenWidth, kScreenWidth);
    self.imageView.image = [UIImage imageNamed:@"0.jpg"];
    [self.view addSubview:self.imageView];
    
    self.label = [[UILabel alloc] init];
    self.label.frame = CGRectMake(0, kScreenWidth + 100, kScreenWidth, 30);
    self.label.text = @"奥黛丽赫本";
    self.label.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:self.label];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

    NSInteger num = arc4random()%7;
    
    // 改变imageView的图片,淡入淡出效果
    [UIView transitionWithView:self.imageView duration:3 options:(UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionCurveLinear) animations:^{
        
        self.imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%ld.jpg", num]];
    } completion:nil];

    // 改变label的文本,二维翻转效果
    [UIView transitionWithView:self.label duration:3 options:(UIViewAnimationOptionTransitionFlipFromLeft | UIViewAnimationOptionCurveLinear) animations:^{
        
        switch (num) {
            case 0:
                self.label.text = @"奥黛丽·赫本";
                break;
            case 1:
                self.label.text = @"苏菲·玛索";
                break;
            case 2:
                self.label.text = @"泰勒·斯威夫特";
                break;
            case 3:
                self.label.text = @"安妮·海瑟薇";
                break;
            case 4:
                self.label.text = @"娜塔丽·波特曼";
                break;
            case 5:
                self.label.text = @"凯拉·奈特利";
                break;
            case 6:
                self.label.text = @"杰西卡·阿尔芭";
                break;
        }
    } completion:nil];
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
1.gif
//
//  ViewController.m
//  CoreAnimation
//
//  Created by 意一yiyi on 2017/11/13.
//  Copyright © 2017年 意一yiyi. All rights reserved.
//

#import "ViewController.h"

#define kScreenWidth [UIScreen mainScreen].bounds.size.width
#define kScreenHeight [UIScreen mainScreen].bounds.size.height

@interface ViewController ()

@property (strong, nonatomic) UIImageView *imageView;
@property (strong, nonatomic) UILabel *label;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.imageView = [[UIImageView alloc] init];
    self.imageView.frame = CGRectMake(0, 64, kScreenWidth, kScreenWidth);
    self.imageView.image = [UIImage imageNamed:@"0.jpg"];
    
    self.label = [[UILabel alloc] init];
    self.label.frame = CGRectMake(0, kScreenWidth + 100, kScreenWidth, 30);
    self.label.text = @"奥黛丽赫本";
    self.label.textAlignment = NSTextAlignmentCenter;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    [UIView transitionWithView:self.view duration:3 options:(UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionCurveLinear) animations:^{
        
        [self.view addSubview:self.imageView];
        [self.view addSubview:self.label];
    } completion:nil];
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
1.gif
(2)给两个视图切换时添加过渡动画
1.gif
上一篇下一篇

猜你喜欢

热点阅读