layer的显式动画,不吹不黑

第壹眼惊艳,小编真的没悟出现在的进口已经提升到这一个境界了,不过后来冷冷清清的看了三遍,抛了滤镜,其实过多地点可能有成都百货上千题材,不吹不黑,它只是国漫的一遍尝试,3个初步,不是极端,更不是完毕。这一代人的文化焦虑把我们都逼得太急了,大家力图地想着把中中原人民共和国的影片动画电视机剧输出,和日美韩的影视化产业肩正官,然则高峰不是毫不费力的,还有太多的动画人在那条路上辛劳跋涉呢,相信以往的它们会更好。

在开班上学Core
Animation提供的layer的隐式动画和layer的显式动画在此以前,大家先来计算一下UIView
block动画
,因为:

android中补间动画分为透明动画,旋转动画,缩放动画和位移移动,动画能够成效在拥有的view上,动画能够独自使用,也得以四个卡通一起利用。

在上一篇中大家商讨了layer的隐式动画,隐式动画是贰个很棒的贯彻layer层基础动画的格局,可是它并无法促成layer层的严重性帧动画和接通动画,所以本篇将学习layer的显式动画,显式动画可分为:品质动画(基础动画和根本帧动画)、动画组连接动画

  • 在实质上付出中我们用的最多的依然view,而不是layer,所以更加多意况下一旦大家要做动画的话,用的依然UIView
    block动画,而不是layer的隐式动画和突显动画;
  • 那里总括一下,能够方便大家在前面两篇学习layer的隐式动画和显式动画时作对照,以期加深对动画片的掌握。
根本写在前边

android动画中装有涉嫌到坐标的地点,坐标原点都以view的左上角。

补间动画只幸而视觉上转移view的情事,但是view实际上照旧以本来的高低在本来的职位上。例如把三个view从左上角移动到了右下角,那3个那些view其实还在左上角,只是在视觉上活动到了右下角,假设view上有点击事件,那么唯有点左上角那么些地点才能触发点击事件,点右下角不会有别的影响。

其次篇隐式动画我们说到隐式动画能够直接效果于layer的可动画属性,不过不能够一向成效于UIView关联的十二分layer的可动画属性,因为UIKit框架把UIView关联的layer的隐式动画给禁止使用了。而显式动画就不一样等了,显式动画也是效益于layer层的,可是它既能够成效于直接创制的layer,也得以成效于view关联的layer,所以大家就不要区分了,直接怼layer就足以了。


一 用代码的法子写补间动画

目录

全体动画的集体属性

此间列出全部动画都有的艺术,包涵八种动画以及AnimationSet,这么些动画片的合集

//设置动画的持续时间
alphaAnimation.setDuration(2000);
 //设置动画播放完毕后是否保持在动画播放完毕的状态
alphaAnimation.setFillAfter(true);
/*
设置动画的重复次数,这里的重复次数指的是动画第一次播放完毕后还会重复播放几次,这里设置为3,就是动画一共播放四次,开始执行一次动画,然后再重复执行三次。
 */
alphaAnimation.setRepeatCount(3);
/*
设置动画重复的模式
有Animation.RESTART:在动画多次播放时每一次都和第一次一样,重复执行
 Animation.REVERSE:每一次执行动画是,和上一次执行相反的操作
例如动画是把view放大到原来的两倍,动画一共执行4次
如果是Animation.RESTART,就会每次都从view本身的大小变到2倍的大小,这一过程一共执行4次
如果是Animation.REVERSE,则第一回从本身大小到2倍,第二回从2倍到本身大小,第三回从2倍到view本身第四回再从view本身到2倍
*/
 alphaAnimation.setRepeatMode(Animation.REVERSE);

用透明动画举例

目录

① 、UIView可动画属性列表

独自使用动画片

1 AlphaAnimation
AlphaAnimation是晶莹剔透动画,能够转移view的发光度
1.1 创制动画

//创建动画,并设置起止透明度,传入的数据是浮点型,需要加f
//参数范围从0到1,0表示完全透明,1表示完全不透明
//第一个参数为开始的时候的透明度,第二个参数为结束的时候的透明度
AlphaAnimation alphaAnimation=new AlphaAnimation(1.0f,0);
alphaAnimation.setDuration(2000);
alphaAnimation.setRepeatCount(3);
alphaAnimation.setRepeatMode(Animation.REVERSE);

1.2 执行动画
第二找到必要实践动画的view,然后调用startAnimation方法,并传到要求实行的动画

imageView.startAnimation(alphaAnimation);

2 ScaleAnimation
缩放动画,控制view的缩放
2.1 创制动画

 /*传入8个参数
前4个参数分别为:
开始长度的缩放比例,终止长度的缩放比例,其实宽度的缩放比例,终止宽度的缩放比例
这四个参数都是浮点型的,代表和原view相比放大或者缩小的比例,1.0代表不变,2.0代表放大到原来的2被,0.5则代表缩小到原来的0.5倍
后四个参数设置缩放的中心点。分别为:
x轴的模式,x轴中心点的位置,y轴的模式,y轴中心点的位置
模式有三种
Animation.RELATIVE_TO_SELF:相对于自己
Animation.RELATIVE_TO_PARENT:相对于父元素
Animation.ABSOLUTE:绝对距离
如果是前两种模式,后面传入的参数代表时父元素或者自己的几倍
例如下面这种写法,代表相对于自己,大小是自己长宽的0.5倍,那么中心点x轴坐标就在空间长度一半的位置
y轴坐标也在控件一半的位置,(android动画中坐标原点都在执行该动画的view的左上角),那个中心点就是该元素的中心。
相对于父元素的也是如此,这两种x,y的坐标是相对的view乘以相应的比例得到的
如果是第三种模式,那个传入的参数谁也不相对,传入的参数是多少,坐标就是多少,坐标原点永远是view的左上角
*/
ScaleAnimation scaleAnimation=new ScaleAnimation(1.0f,2.0f,1.0f,2.0f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);

可以再设置有个别别的急需的参数
2.2 执行动画
履行动画都是如出一辙的操作
3 RotateAnimation
旋转动画,控制view的转动操作
3.1 成立动画

/*
传入6个参数,前2个参数是开始时旋转的角度,和结束时旋转的角度
正数代表顺时针,负数代表逆时针
后四个参数为设置旋转的中心点,和ScaleAnimation设置中心点一致
*/
RotateAnimation rotateAnimation=new RotateAnimation(0,360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);

能够安装有些别的的参数
3.2 执行动画
实践动画都以千篇一律的
4 TranslateAnimation
位移动画,控制view的活动
4.1 创造动画

/*
传入8个参数
一共四组,分别为
起始时view的左上角x轴坐标
结束时view的左上角x坐标
起始时view的左上角y坐标
结束时view的左上角y坐标
view左上角坐标默认为(0,0)
每一组是一个模式加一个值组成的,模式和值进行计算得出实际的坐标值
有关模式的可以看ScaleAnimation中的讲解
 */
TranslateAnimation translateAnimation=new TranslateAnimation(Animation.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,0.5f);

能够安装有个别别的的参数
4.2 执行动画

① 、属性动画(CAPropertyAnimation)

二、什么是UIView block动画?

动画片合集

5 AnimationSet
动画的合集,使用它能够决定前边列出的二种动画中的一种也许三种同步实施
5.1 创建AnimationSet

//传入一个boolean类型的参数,这个参数控制的是动画执行时是匀速执行还是不匀速执行
//这个参数不好用,直接都传入true,让他匀速执行就可以
 AnimationSet animationSet=new AnimationSet(true);

5.2 将动画片参加到AnimationSet中

animationSet.addAnimation(translateAnimation);
animationSet.addAnimation(scaleAnimation);
animationSet.addAnimation(alphaAnimation);
animationSet.addAnimation(rotateAnimation);

5.3
能够设置某些参数,尽管在set中装置参数,就会对set中享有的卡通起效果,每一种动画自身设置的参数只对团结起效用

animationSet.setDuration(2000);

5.4 执行动画

imageView.startAnimation(animationSet);
一 、基础动画(CABasicAnimation)
① 、UIView block动画的定义、本质及能做什么动画
二 用xml的主意定义补间动画

用代码定义的动画都足以用xml的艺术贯彻
首先在res目录下树立1个anim目录
再在anim目录下树立三个动画文件,在此动画文件中开端写xml

(1)什么是基础动画?
二 、UIView block动画的归类
相同先说有着动画的共用属性

毫无多说,和地方完全一致,须求说一点,有时这么些属性没有代码提醒,直接手打出来就行。

android:duration="2000"
android:repeatMode="restart"
android:repeatCount="3"
android:fillAfter="true"

1 透明动画
1.1 在xml文件中写动画

<!--需要说明的有两个参数
 fromAlpha,toAlpha,分别代表开始的透明度和结束的透明度,大小从0到1
在xml中浮点型不用加f
-->
<alpha
android:fromAlpha="1"
android:toAlpha="0"
android:duration="2000"
android:repeatMode="restart"
android:repeatCount="3"
android:fillAfter="true"/>

1.2 执行动画

//用AnimationUtils工具类把动画加载进行,传入两个参数,一个上下文,一个动画资源的id
AlphaAnimation animation=AnimationUtils.loadAnimation(this,R.anim.animation);
//执行动画
imageView.startAnimation(animationSet);

2 缩放动画
2.1 创设动画

 <!--
    fromXScale:开始时长度的大小,参数代表这个长度和view自身长度的比例,即这个长度是view自身长度的几倍
    toXScale:结束是长度的大小
    fromYScale:开始时宽度的大小
    toYScale:结束是宽度的大小
    pivotX:旋转中心点横坐标,可以传入三种类型的参数,
    50%,代表横坐标view自身的长度的50%
    50%p,代表横坐标是父元素控件的50%
    50,代表横坐标就是50。
    坐标原点是view的左上角坐标
    pivotY:旋转中心点纵坐标
    同pivotX
    -->
    <scale
        android:fromXScale="1"
        android:toXScale="2"
        android:fromYScale="1"
        android:toYScale="2"
        android:pivotX="50%"
        android:pivotY="50%"/>

2.2 执行动画
加载动画,执行动画
3 旋转动画
3.1 创造动画

 <!--
    fromDegrees:开始角度
    toDegrees:结束角度
    pivotX,pivotY:设置旋转中心点,和scale中的一样
    -->
    <rotate
        android:fromDegrees="0"
        android:toDegrees="360"
        android:pivotX="50%"
        android:pivotY="50%"/>

3.2 执行动画
加载动画,并履行动画
4 位移动画
4.1 创设动画

 <!--
    fromXDelta:动画开始时view左上角x坐标的位置
    toXDelta:动画结束时view左上角x坐标的位置
    fromYDelta:动画开始时view左上角坐标的位置
    toYDelta:动画结束时view左上角y坐标的位置
    这四个参数都可以传入
    50%,代表横坐标view自身的长度的50%
    50%p,代表横坐标是父元素控件的50%
    50,代表横坐标就是50。
    坐标原点是原始view的左上角坐标
    -->
    <translate
        android:fromXDelta="0"
        android:toXDelta="0"
        android:fromYDelta="0"
        android:toYDelta="50%"/>

4.2 执行动画
加载动画,执行动画

(2)怎样行使基础动画?
(1)UIView block基础动画(UIView block属性动画的一种)
动画片合集

5 set 动画的合集
那时候根成分是set成分,set成分中可以写入五个卡通
set能够设置属性,set中的属性全体动画共享,动画内部的习性唯有该动画自个儿能够选择
5.1 创建动画

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000">
    <alpha
        android:fromAlpha="1"
        android:toAlpha="0"
        android:duration="2000"
        android:repeatMode="restart"
        android:repeatCount="3"
        android:fillAfter="true"/>
    <translate
        android:fromXDelta="0"
        android:toXDelta="0"
        android:fromYDelta="0"
        android:toYDelta="50%"/>
    <scale
        android:fromXScale="1"
        android:toXScale="2"
        android:fromYScale="1"
        android:toYScale="2"
        android:pivotX="50%"
        android:pivotY="50%"/>
    <rotate
        android:fromDegrees="0"
        android:toDegrees="360"
        android:pivotX="50%"
        android:pivotY="50%"/>
</set>

5.2 执行动画

 AnimationSet set= (AnimationSet) AnimationUtils.loadAnimation(this,R.anim.animation);
imageView.startAnimation(set);
(3)举例表达基础动画必要留意的八个地点及缓解
①怎么是UIView block基础动画?
② 、关键帧动画(CAKeyframeAnimation)
layer的显式动画,不吹不黑。②哪些采用UIView block基础动画?
(1)什么是重视帧动画?
(2)UIView block关键帧动画(UIView block属性动画的一种)
(2)如何运用首要帧动画?
①怎么着是UIView block关键帧动画?
(3)举例说明设置关键帧的五个点子:数组关键帧法和途径关键帧法
②怎么着使用UIView block关键帧动画?

二、动画组(CAAnimationGroup)

(3)UIView block过渡动画
(1)什么是动画组?
①什么样是UIView block过渡动画?
(2)怎么样行使动画组?
②什么使用UIView block过渡动画?

③ 、过渡动画

叁 、怎么样选用UIView block动画?(应用举例)

(1)什么是过渡动画?
① 、UIView block基础动画举例
(2)如何运用过渡动画?
② 、UIView block关键帧动画举例

四 、什么景况下利用呈现动画


叁 、UIView block过渡动画举例

澳门新葡萄京娱乐 ,① 、属性动画(CAPropertyAnimation)

大家知道想要做属性动画的话,能够直接行使UIView的block属性动画,也得以动用layer的隐式动画来贯彻,那么那里的layer展现动画的质量动画正是大家兑现属性动画的第三种采纳。

属性动画又有多个子类,大家常常首要选拔那三个子类来做动画,它们是基础动画(CABasicAnimation)重点帧动画(CAKeyframeAnimation),接下去大家将分别介绍:

壹 、UIView可动画属性列表

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

二、什么是UIView block动画?

(1)什么是基础动画?

率先篇中UIView block基础动画说过了,类似。

① 、UIView block动画的定义、本质及能做怎么样动画
  • 定义:UIView block动画正是用来在view层做动画的一种动画机制

  • 本质:UIView
    block动画的实质就是对layer的隐式动画或显式动画做了一层封装,提供简单的Api,方便我们开发者使用。
    具体来说UIView
    block基础动画是对layer的隐式动画做了包装(因为它们同样能够设置过渡效果/图层行为,展现动画的功底动画不能够安装图层行为,当然显式动画的连通动画也可以成效于可动画属性,但是前边讲到隐式动画应该会清楚UIView
    block基础动画是对layer的隐式动画做了包装),UIView
    block关键帧动画是对layer的呈现动画的要紧帧动画做了打包,UIView
    block过渡动画是对layer的显示动画的接入动画做了打包。

  • 能做什么动画:

    • 上面我们会涉及UIView block动画可分为UIView block属性动画和UIView
      block过渡动画,而UIView block属性动画又可分为UIView
      block基础动画和UIView block关键帧动画。

    • UIView
      block属性动画能做哪些动画:
      那么从UIView的可动画属性列表大家能够看看,UIView
      block属性动画能够用来对view做背景象变化的动画片、view显隐性变化的卡通以及view的移位、缩放和旋转的仿射变换动画
      三种场景下的卡通,在那之中履行叁次UIView
      block基础动画只可以改变一个属性值二次,执行二次UIView
      block关键帧动画能够安装八个至关心尊崇要帧所以能改变一个属性值数次

    • UIView block过渡动画能做哪些动画:UIView
      block属性动画只好对UIView的可动画属性做动画,可是假诺我们未来想要对view的非动画属性改变时(如label的文本,imageView的图纸等)做动画,甚至是对view的少数行为(如view的丰硕和移除,四个view之间切换)做动画,那就不得不接纳过渡动画了。

  • 由此我们也就领悟了干吗要引入UIView block动画:
    • 首先、当然正是UIView
      block动画是职能于view层,对layer的隐式动画或显式动画做了一层封装,提供简单的Api,方便我们开发者使用;
    • 其次、UIView
      block属性动画可以帮忙大家在改变view的可动画属性时能做动画效果。如若看到后边一篇隐式动画,我们会分晓在转移layer的可动画属性时,即使大家怎么都不做直接修改layer的属性值,这些改变的进度也会默许有三个动画片,它就是隐式动画;可是当大家在转移view的可动画属性时,是绝非隐式动画的,假使大家怎么样都不做,属性就会一贯跳变到新值,所以为了达成改变view的习性时能有动画,大家就得利用UIView
      block动画来贯彻了。
    • 其③ 、UIView
      block过渡动画能够扶助大家在改动view的不行变属性可能对view做一些行为能做动画。
(2)如何行使基础动画?

基本功动画的应用也很不难,只必要按以下多少个步骤来就足以了:

  • 开创一个基础动画
  • 设置好基础动画的代办(回调中要工作的)
  • 钦命基础动画要改变的习性
  • 给基础动画2个早先值(不给也行,会私下认可为layer开始状态对应属性的值)
  • 给基础动画1个完成值
  • 再内定一些基础动画的别的设置(如动画时间长度、重复次数等)
  • 然后把那么些基础动画添加到layer上,动画就会起来履行了
二 、UIView block动画的归类

UIView block动画可分为UIView block属性动画和UIView
block过渡动画,而UIView block属性动画又可分为UIView
block基础动画和UIView block关键帧动画,接下去大家将独家介绍UIView
block基础动画
UIView block关键帧动画UIView block过渡动画

(3)举个例子

给customLayer背景象的改动加一个动画片,给customLayer1切圆角的转移加1个卡通

(清单3.1)

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

#import "ViewController.h"

@interface ViewController ()<CAAnimationDelegate>

@property (strong, nonatomic) CALayer *customLayer;
@property (strong, nonatomic) CALayer *customLayer1;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.customLayer = [[CALayer alloc] init];
    self.customLayer.frame = CGRectMake(100, 100, 100, 100);
    self.customLayer.backgroundColor = [UIColor redColor].CGColor;
    [self.view.layer addSublayer:self.customLayer];

    self.customLayer1 = [[CALayer alloc] init];
    self.customLayer1.frame = CGRectMake(100, 250, 100, 100);
    self.customLayer1.backgroundColor = [UIColor redColor].CGColor;
    [self.view.layer addSublayer:self.customLayer1];
}

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

    CABasicAnimation *basicAnimation = [[CABasicAnimation alloc] init];
    NSLog(@"customLayer背景色basicAnimation===%@", basicAnimation);
    basicAnimation.delegate = self;
    basicAnimation.keyPath = @"backgroundColor";
    basicAnimation.toValue = (__bridge id _Nullable)([UIColor orangeColor].CGColor));
    basicAnimation.duration = 3;
    [self.customLayer addAnimation:basicAnimation forKey:nil];

    CABasicAnimation *basicAnimation1 = [[CABasicAnimation alloc] init];
    NSLog(@"customLayer1切圆角basicAnimation1===%@", basicAnimation1);
    basicAnimation1.delegate = self;
    basicAnimation1.keyPath = @"cornerRadius";
    basicAnimation1.toValue = @(50);
    basicAnimation1.duration = 3;
    [self.customLayer1 addAnimation:basicAnimation1 forKey:nil];
}

- (void)animationDidStart:(CAAnimation *)anim {

    NSLog(@"动画开始了===%@", anim);
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {

    NSLog(@"动画结束了===%@", anim);
}


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

@end

澳门新葡萄京娱乐 1

1.gif

运转,大家得以看到真的有了动画片,不过也发觉了如下难题:

  • 动画片在形成之后又跳回到开头状态了,那是怎么?
    • 针对那几个标题:其实基础动画只是虚拟出来的视觉效果,并没有当真改变layer做动画那多少个属性的值,所以大家要在动画甘休把layer做动画的不胜属性的值修改为动画片的扫尾值。同时大家要留意在动画甘休重新设置layer属性值的时候,要记得关闭layer的隐式动画,不然既会有底子动画带来的动画片也会有隐式动画带来的卡通,就重叠了。修改动画甘休的代办方法如下:

(清单3.2)

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {

    NSLog(@"动画结束了===%@", anim);

    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    self.customLayer.backgroundColor = [UIColor orangeColor].CGColor;
    self.customLayer1.cornerRadius = 50;
    [CATransaction commit];
}

澳门新葡萄京娱乐 2

1.gif

运转,发现能够了,可是又发现多个难题:

  • 更改layer属性值的时候,layer神速地闪回到伊始状态才变成甘休值,这是干什么?(模拟器是不曾难点的,所以调节和测试动画一定要在真机上整)

    • 本着这么些难点:大家需求在动画结束之后,设置layer保持哪一帧,须求安装为保持动画结束后的那一帧,并且以前设置动画结束后不自动移除,而是在须求的时候手动移除。通过这三个属性的装置(即animationremovedOnCompletionfillMode四个属性),动画在收尾时就不会赶快闪回起始状态再变成甘休状态了,代码如下:

(清单3.3)

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

    CABasicAnimation *basicAnimation = [[CABasicAnimation alloc] init];
    NSLog(@"customLayer背景色basicAnimation===%@", basicAnimation);
    basicAnimation.delegate = self;
    basicAnimation.keyPath = @"backgroundColor";
    basicAnimation.toValue = (__bridge id _Nullable)([UIColor orangeColor].CGColor);
    basicAnimation.duration = 3;
    basicAnimation.removedOnCompletion = NO;// 动画结束后不自动移除动画
    basicAnimation.fillMode = kCAFillModeForwards;// 动画结束后保持结束时的那一帧
    [self.customLayer addAnimation:basicAnimation forKey:nil];

    CABasicAnimation *basicAnimation1 = [[CABasicAnimation alloc] init];
    NSLog(@"customLayer1切圆角basicAnimation1===%@", basicAnimation1);
    basicAnimation1.delegate = self;
    basicAnimation1.keyPath = @"cornerRadius";
    basicAnimation1.toValue = @(50);
    basicAnimation1.duration = 3;
    basicAnimation1.removedOnCompletion = NO;
    basicAnimation1.fillMode = kCAFillModeForwards;
    [self.customLayer1 addAnimation:basicAnimation1 forKey:nil];
}
  • 还有2个难题不怕,如若我们在1个控制器里面创立了多少个卡通的话(比如(清单3.1)中大家独家给customLayer和customLayer1创建了2个卡通),那么那多个卡通都会走到同叁个动画截止的代办方法里,大家想要达到的卡通目标是customLayer的动画停止时改变customLayer的背景观,customLayer1的卡通片甘休时改变customLayer1的圆角,而不是(清单3.1)中那种把customLayer和customLayer1两者同时更改,那怎么做吧?有三种格局,我们独家看一下:

    • 艺术一:我们看看动画截止的代理方法是有个参数anim把动画带回来的,那是还是不是大家得以把大家创建的动画片成立成属性,来那边比对,对上号之后更改相应layer的本性不就可以了呗。看似很简短完美的章程。可是你也看看大家有打字与印刷操作了,看下控制台的输出吧:

(清单3.3)

2018-01-16 11:06:09.205151+0800 CoreAnimation[1582:390479] customLayer背景色basicAnimation===<CABasicAnimation: 0x1c803aa40>
2018-01-16 11:06:09.205444+0800 CoreAnimation[1582:390479] customLayer1切圆角basicAnimation1===<CABasicAnimation: 0x1c803ab20>
2018-01-16 11:06:09.205989+0800 CoreAnimation[1582:390479] 动画开始了===<CABasicAnimation: 0x1c803ab40>
2018-01-16 11:06:09.206101+0800 CoreAnimation[1582:390479] 动画开始了===<CABasicAnimation: 0x1c803ab00>
2018-01-16 11:06:12.207372+0800 CoreAnimation[1582:390479] 动画结束了===<CABasicAnimation: 0x1c803ab40>
2018-01-16 11:06:12.207838+0800 CoreAnimation[1582:390479] 动画结束了===<CABasicAnimation: 0x1c803ab00>

大家咋舌地发现,大家创立的底子动画和卡通初始、截至代理方法带回去的动画并不是二个卡通。因为动画开头、甘休代理方法带回来的动画片是大家成立的根底动画的深拷贝,omg,那种办法败北了。

  • 方法二:回到(清单3.1)能够见到,大家在给layer添加动画的法门-addAnimation: forKey:的key大家给的是空,其实大家得以在这些地点给animation关联贰个key,这一个key其实就是我们能收获到内定animation的绝无仅有标识。大家修改代码如下:

(清单3.4)

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

#import "ViewController.h"

@interface ViewController ()<CAAnimationDelegate>

@property (strong, nonatomic) CALayer *customLayer;
@property (strong, nonatomic) CALayer *customLayer1;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.customLayer = [[CALayer alloc] init];
    self.customLayer.frame = CGRectMake(100, 100, 100, 100);
    self.customLayer.backgroundColor = [UIColor redColor].CGColor;
    [self.view.layer addSublayer:self.customLayer];

    self.customLayer1 = [[CALayer alloc] init];
    self.customLayer1.frame = CGRectMake(100, 250, 100, 100);
    self.customLayer1.backgroundColor = [UIColor redColor].CGColor;
    [self.view.layer addSublayer:self.customLayer1];
}

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

    CABasicAnimation *basicAnimation = [[CABasicAnimation alloc] init];
    NSLog(@"customLayer背景色basicAnimation===%@", basicAnimation);
    basicAnimation.delegate = self;
    basicAnimation.keyPath = @"backgroundColor";
    basicAnimation.toValue = (__bridge id _Nullable)([UIColor orangeColor].CGColor);
    basicAnimation.duration = 3;
    [self.customLayer addAnimation:basicAnimation forKey:@"basicAnimation"];

    CABasicAnimation *basicAnimation1 = [[CABasicAnimation alloc] init];
    NSLog(@"customLayer1切圆角basicAnimation1===%@", basicAnimation1);
    basicAnimation1.delegate = self;
    basicAnimation1.keyPath = @"cornerRadius";
    basicAnimation1.toValue = @(50);
    basicAnimation1.duration = 3;
    [self.customLayer1 addAnimation:basicAnimation1 forKey:@"basicAnimation1"];
}

- (void)animationDidStart:(CAAnimation *)anim {

    NSLog(@"动画开始了===%@", anim);
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {

    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    self.customLayer.backgroundColor = [UIColor orangeColor].CGColor;
    self.customLayer1.cornerRadius = 50;
    [CATransaction commit];

    NSLog(@"动画结束了===%@, %@", [self.customLayer animationForKey:@"basicAnimation"], self.customLayer1.animationKeys);
}


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

@end

而是运维,发现输出皆以空,不亮堂为何?待解。

(清单3.5)

2018-01-16 13:12:46.985628+0800 CoreAnimation[1695:434274] customLayer背景色basicAnimation===<CABasicAnimation: 0x1c803e280>
2018-01-16 13:12:46.986083+0800 CoreAnimation[1695:434274] customLayer1切圆角basicAnimation1===<CABasicAnimation: 0x1c803e360>
2018-01-16 13:12:46.986961+0800 CoreAnimation[1695:434274] 动画开始了===<CABasicAnimation: 0x1c803e380>
2018-01-16 13:12:46.987066+0800 CoreAnimation[1695:434274] 动画开始了===<CABasicAnimation: 0x1c803e340>
2018-01-16 13:12:49.988287+0800 CoreAnimation[1695:434274] 动画结束了===(null), (null)
2018-01-16 13:12:49.988567+0800 CoreAnimation[1695:434274] 动画结束了===(null), (null)
  • 格局三:幸运的是,大家还有第二种方法。正是Core
    Animation完成了KVC,所以能够随便给二个动画贴标签,而且key和value都以id类型的
    ,所以那边我们就能够吧layer作为value给基础动画贴个标签,然后再动画甘休的回调里就可以判明出实际是哪个动画结束了。修改代码如下:

(清单3.6)

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

#import "ViewController.h"

@interface ViewController ()<CAAnimationDelegate>

@property (strong, nonatomic) CALayer *customLayer;
@property (strong, nonatomic) CALayer *customLayer1;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.customLayer = [[CALayer alloc] init];
    self.customLayer.frame = CGRectMake(100, 100, 100, 100);
    self.customLayer.backgroundColor = [UIColor redColor].CGColor;
    [self.view.layer addSublayer:self.customLayer];

    self.customLayer1 = [[CALayer alloc] init];
    self.customLayer1.frame = CGRectMake(100, 250, 100, 100);
    self.customLayer1.backgroundColor = [UIColor redColor].CGColor;
    [self.view.layer addSublayer:self.customLayer1];
}

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

    CABasicAnimation *basicAnimation = [[CABasicAnimation alloc] init];
    NSLog(@"customLayer背景色basicAnimation===%@", basicAnimation);
    basicAnimation.delegate = self;
    basicAnimation.keyPath = @"backgroundColor";
    basicAnimation.toValue = (__bridge id _Nullable)([UIColor orangeColor].CGColor);
    basicAnimation.duration = 3;
    [basicAnimation setValue:self.customLayer forKey:@"tag"];
    [self.customLayer addAnimation:basicAnimation forKey:nil];

    CABasicAnimation *basicAnimation1 = [[CABasicAnimation alloc] init];
    NSLog(@"customLayer1切圆角basicAnimation1===%@", basicAnimation1);
    basicAnimation1.delegate = self;
    basicAnimation1.keyPath = @"cornerRadius";
    basicAnimation1.toValue = @(50);
    basicAnimation1.duration = 3;
    [basicAnimation1 setValue:self.customLayer1 forKey:@"tag"];
    [self.customLayer1 addAnimation:basicAnimation1 forKey:nil];
}

- (void)animationDidStart:(CAAnimation *)anim {

    NSLog(@"动画开始了===%@", anim);
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {

    if ([anim valueForKey:@"tag"] == self.customLayer) {

        [CATransaction begin];
        [CATransaction setDisableActions:YES];
        self.customLayer.backgroundColor = [UIColor orangeColor].CGColor;
        [CATransaction commit];
    }

    if ([anim valueForKey:@"tag"] == self.customLayer1) {

        [CATransaction begin];
        [CATransaction setDisableActions:YES];
        self.customLayer1.cornerRadius = 50;
        [CATransaction commit];
    }

    NSLog(@"动画结束了===%@, %@", [self.customLayer animationForKey:@"basicAnimation"], self.customLayer1.animationKeys);
}


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

@end
(1)UIView block基础动画
贰 、关键帧动画(CAKeyframeAnimation)
①什么是UIView block基础动画?

UIView block基础动画是UIView
block属性动画的一种,它用来对view的可动画属性做动画,不过施行二回UIView
block基础动画只可以变更三个属性值一回,因为我们是三次性把属性值直接设置为目的值的
(就算要想更改数十二遍品质的值,能够在动画停止后再开头四个基础动画再改1遍属性值,如此循环往复,但有贰个更简短的主意正是使用UIView
block关键帧动画,后边会说到)它至关心保养要分上面八种:

  • 最精简的block基础动画

[UIView animateWithDuration:// 动画时长
                 animations:^{

                     // 要改变的属性
                 }];
  • 拉动画形成回调的block基础动画

[UIView animateWithDuration:// 动画时长
                 animations:^{

                     // 要改变的属性
                 } completion:^(BOOL finished) {

                     // 动画完成的回调
                 }];
  • 可安装延时和自定义动画过渡效果的block基础动画

[UIView animateWithDuration:// 动画时长
                      delay:// 延时多长时间后开始执行动画
                    options:// 可自定义动画的过渡效果,来替换掉系统默认的平滑过渡效果
                 animations:^{

                     // 要改变的属性
                 } completion:^(BOOL finished) {

                     // 动画完成的回调
                 }];

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

  • 一般就安装下连接动画效果和连通动画时间曲线就足以了;

  • 如若和后边layer显式动画的连片动画的type和subType相比一下,会发现那里的连接动画效果是把layer显式动画的交接动画的type和subType组合起来了,而且那里的连通动画效果要比layer显式动画的连通动画的职能少得多,只有淡入淡出、正面背面二维翻转、翻页效果三种而已。

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

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

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

UIViewAnimationOptionAutoreverse// 执行动画回路
UIViewAnimationOptionLayoutSubviews// 执行动画时布局子控件
UIViewAnimationOptionAllowAnimatedContent// 执行动画时重绘视图
UIViewAnimationOptionBeginFromCurrentState// 从当前状态开始执行动画
UIViewAnimationOptionShowHideTransitionViews// 显示视图时显示或隐藏而不是移除或添加
UIViewAnimationOptionOverrideInheritedOptions// 不继承父动画设置
UIViewAnimationOptionOverrideInheritedCurve// 忽略嵌套动画的曲线设置
UIViewAnimationOptionOverrideInheritedDuration// 忽略嵌套动画的执行时间设置
  • Spring动画:正是指在改变属性的时候,属性值会在对象值附近摆动,类似弹簧这种的弹性动画

[UIView animateWithDuration:// 动画时长
                      delay:// 延时多长时间后开始执行动画
     usingSpringWithDamping:// 弹性效果的阻尼:范围0~1,数值越小弹性效果越明显,震得越久才能停下来
      initialSpringVelocity:// 弹性效果的初始速度:数值越大开始弹性动画时初始速度越快
                    options:// 可自定义动画的过渡效果,来替换掉系统默认的平滑过渡效果
                 animations:^{

                     // 要改变的属性
                 } completion:^(BOOL finished) {

                     // 动画完成的回调
                 }];
(1)什么是首要帧动画?

第①帧动画同样也是性质动画的1个子类,它也是用来做layer层的习性动画的,它能够用来做一些比较复杂的个性动画。比如说,大家来看基础动画的三个弊端正是它只必要给3个起初值和了结值就可以了,那样的意义在田地下就展现平板甚至不可能满足须求。而根本帧动画就足以帮忙大家摆脱基础动画仅仅是开端值和甘休值的封锁,能够随心所欲安装一而再串关键帧,甚至是绘制曲线。

②什么使用UIView block基础动画?

小编们只须要在UIView
block基础动画的animationsblock里一向把可动画属性改变为对象值就能够了。

(2)怎么着选拔首要帧动画?

根本帧动画的施用也极粗略,只供给按以下多少个步骤来就足以了:

  • 创设三个最首要帧动画
  • 设置好重庆大学帧动画的代办(回调中要干活的)
  • 点名关键帧动画要改成的习性
  • 给关键帧动画的values属性设置一写关键帧(注意第②帧不能大致,它不会暗中同意为layer伊始状态的属性值,第1帧大家要积极设置为layer初始状态的属性值,不然会从起先状态的值直接跳变到第①帧)的数组或然路径绘制设置重庆大学帧法
  • 再钦赐一些基础动画的别的设置(如动画时间长度、重复次数等)
  • 接下来把那几个基础动画添加到layer上,动画就会伊始推行了
(2)UIView block关键帧动画
(3)举个例子
  • values数组关键帧法:改变customLayer的背景象
    (清单3.7)

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

#import "ViewController.h"

@interface ViewController ()<CAAnimationDelegate>

@property (strong, nonatomic) CALayer *customLayer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.customLayer = [[CALayer alloc] init];
    self.customLayer.frame = CGRectMake(100, 100, 100, 100);
    self.customLayer.backgroundColor = [UIColor redColor].CGColor;
    [self.view.layer addSublayer:self.customLayer];
}

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

    CAKeyframeAnimation *basicAnimation = [[CAKeyframeAnimation alloc] init];
    basicAnimation.delegate = self;
    basicAnimation.keyPath = @"backgroundColor";
    basicAnimation.values = @[
                              (__bridge id _Nullable)([UIColor redColor].CGColor),// 第一帧我们要主动设置为layer初始状态的属性值
                              (__bridge id _Nullable)([UIColor orangeColor].CGColor),
                              (__bridge id _Nullable)([UIColor yellowColor].CGColor),
                              (__bridge id _Nullable)([UIColor greenColor].CGColor)
                              ];
    basicAnimation.duration = 3;
    [basicAnimation setValue:self.customLayer forKey:@"tag"];
    [self.customLayer addAnimation:basicAnimation forKey:nil];
}

- (void)animationDidStart:(CAAnimation *)anim {

    NSLog(@"动画开始了");
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {

    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    self.customLayer.backgroundColor = [UIColor greenColor].CGColor;
    [CATransaction commit];

    NSLog(@"动画结束了");
}


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

@end

澳门新葡萄京娱乐 3

1.gif

  • 路线关键帧法:让layer沿叁个贰遍贝塞尔曲线移动

作者们精通UIView
block关键帧动画只好设置数组关键帧,所以只要部分场景下,大家必要连接的关键帧就需要选用显式动画的要害帧动画了,它支持路径关键帧。

(清单3.8)

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

#import "ViewController.h"

@interface ViewController ()<CAAnimationDelegate>

@property (strong, nonatomic) UIImageView *customImageView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.customImageView = [[UIImageView alloc] init];
    self.customImageView.frame = CGRectMake(100, 100, 100, 100);
    self.customImageView.backgroundColor = [UIColor clearColor];
    self.customImageView.image = [UIImage imageNamed:@"汽车"];
    [self.view addSubview:self.customImageView];
}

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

    CAKeyframeAnimation *keyframeAnimation = [[CAKeyframeAnimation alloc] init];
    keyframeAnimation.delegate = self;
    keyframeAnimation.keyPath = @"position";

    // 绘制一个三次贝塞尔曲线
    UIBezierPath *bezierPath = [[UIBezierPath alloc] init];
    [bezierPath moveToPoint:CGPointMake(150, 150)];
    [bezierPath addCurveToPoint:CGPointMake(150, 450) controlPoint1:CGPointMake(250, 250) controlPoint2:CGPointMake(50, 350)];
    // 绘制一个shapeLayer放在屏幕上显得更形象
    CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init];
    shapeLayer.path = bezierPath.CGPath;
    shapeLayer.fillColor = [UIColor clearColor].CGColor;
    shapeLayer.strokeColor = [UIColor magentaColor].CGColor;
    shapeLayer.lineWidth = 3.0f;
    [self.view.layer addSublayer:shapeLayer];

    keyframeAnimation.path = bezierPath.CGPath;
    keyframeAnimation.duration = 3;
    keyframeAnimation.rotationMode = kCAAnimationRotateAuto;// 让layer根据曲线的切线自动旋转方向
    [keyframeAnimation setValue:self.customImageView forKey:@"tag"];
    [self.customImageView.layer addAnimation:keyframeAnimation forKey:nil];
}

- (void)animationDidStart:(CAAnimation *)anim {

    NSLog(@"动画开始了");
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {

    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    self.customImageView.layer.position = CGPointMake(150, 450);
    [CATransaction commit];

    NSLog(@"动画结束了");
}


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

@end

澳门新葡萄京娱乐 4

1.gif

①怎么是UIView block关键帧动画?

地方说到了UIView block基础动画是UIView
block属性动画的一种,而那里的UIView block关键帧动画也是UIView
block属性动画的一种,它也是用来对view的可动画属性做动画的,只不过效果说不定在一些场景下比基础动画要便宜也许加上一些,然而进行一回UIView
block关键帧动画能够安装四个关键帧所以能改变3个属性值数次,而不是三遍性把属性值设置指标值

供给注意的是:UIView
block关键帧动画设置重要帧只好通过扩充关键帧方法来设置,相当于layer显示动画的要紧帧动画的数组关键帧法,这几个是不帮助路径关键帧法的。

  • UIView block关键帧动画

[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里把可动画属性改变为目的值就能够了。

(1)什么是动画组?

卡通组其实很简短了,它是别的二个后续于CAAnimation的子类,它提供了3个animations的数组属性用来把过多个耳熟能详感动画组成起来共同实施和决定,制止一堆动画单个控制的累赘

理所当然了,我们绝不组合卡通而是把单个单个的卡通分别添在同三个layer上也是能够的。

(3)UIView block过渡动画
(2)怎么着选取动画组?

很简短了,创设单个单个的卡通,然后把那一个单个单个的动画赋值给动画组的animations数组,然后把那几个动画组添加到layer上,这一堆动画就会起来还要推行了。

举例:把上边包车型客车根底动画和关键帧动画组成起来,构成动画组。
(清单3.9)

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

#import "ViewController.h"

@interface ViewController ()<CAAnimationDelegate>

@property (strong, nonatomic) CALayer *customLayer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.customLayer = [[CALayer alloc] init];
    self.customLayer.frame = CGRectMake(100, 100, 100, 100);
    self.customLayer.backgroundColor = [UIColor redColor].CGColor;
    self.customLayer.contents = (__bridge id _Nullable)([UIImage imageNamed:@"汽车"].CGImage);
    self.customLayer.contentsScale = [UIScreen mainScreen].scale;
    [self.view.layer addSublayer:self.customLayer];
}

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

    // 基础动画
    CABasicAnimation *basicAnimation = [[CABasicAnimation alloc] init];
    basicAnimation.keyPath = @"backgroundColor";
    basicAnimation.toValue = (__bridge id _Nullable)([UIColor orangeColor].CGColor);

    // 关键帧动画
    CAKeyframeAnimation *keyframeAnimation = [[CAKeyframeAnimation alloc] init];
    keyframeAnimation.keyPath = @"position";
    // 绘制一个三次贝塞尔曲线
    UIBezierPath *bezierPath = [[UIBezierPath alloc] init];
    [bezierPath moveToPoint:CGPointMake(150, 150)];
    [bezierPath addCurveToPoint:CGPointMake(150, 450) controlPoint1:CGPointMake(250, 250) controlPoint2:CGPointMake(50, 350)];
    // 绘制一个shapeLayer放在屏幕上显得更形象
    CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init];
    shapeLayer.path = bezierPath.CGPath;
    shapeLayer.fillColor = [UIColor clearColor].CGColor;
    shapeLayer.strokeColor = [UIColor magentaColor].CGColor;
    shapeLayer.lineWidth = 3.0f;
    [self.view.layer addSublayer:shapeLayer];
    keyframeAnimation.path = bezierPath.CGPath;
    keyframeAnimation.rotationMode = kCAAnimationRotateAuto;// 让layer根据曲线的切线自动旋转方向

    // 动画组
    CAAnimationGroup *animationGroup = [[CAAnimationGroup alloc] init];
    animationGroup.delegate = self;
    animationGroup.animations = @[basicAnimation, keyframeAnimation];
    animationGroup.duration = 3;
    [self.customLayer addAnimation:animationGroup forKey:nil];
}

- (void)animationDidStart:(CAAnimation *)anim {

    NSLog(@"动画开始了");
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {

    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    self.customLayer.backgroundColor = [UIColor orangeColor].CGColor;
    self.customLayer.position = CGPointMake(150, 450);
    [CATransaction commit];

    NSLog(@"动画结束了");
}


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

@end

澳门新葡萄京娱乐 5

1.gif

①什么样是UIView block过渡动画?

前方大家上学了UIView block基础动画和UIView
block关键帧动画,但大家知道它俩其实都以UIView
block属性动画,即只好用来对view的可动画属性做动画。那么一旦大家未来想要对view的非动画属性改变时(如label的文书,imageView的图片等)做动画,甚至是对view的有些行为(如view的增进和移除,多个view之间切换)做动画,那就只好选拔连通动画了。

与此同时大家也能够见到,上边UIView block基础动画和UIView
block关键帧动画的一些方法里也提供了联网效果10分配置,也正是说过渡动画也是能够效率于可动画属性的,然而还足以做可动画属性之外的重重效应。

联网动画的连通效果可参见UIView
block基础动画的连通效果,是一模一样的。

  • 给单个视图的不可动画属性或视图行为添加过渡动画

[UIView transitionWithView:// 要做动画的视图
                  duration:// 动画时长
                   options:// 过渡动画效果
                animations:^{

                    // 要改变的不可动画属性或图层行为
                } completion:^(BOOL finished) {

                    // 动画完成的回调
                }];
  • 给五个视图切换时添加过渡动画

注意:

  • 那一个法子的连通效果是反映在fromView和toView的父视图上的
  • 这几个主意不必要超前把fromView和toView都添在父视图上,只须要先添加fromView就足以了
  • 其一办法在动画进程中,会自动把fromView会从父视图中移除,并把toView添加到父视图上

[UIView transitionFromView:// 旧视图
                    toView:// 新视图
                  duration:// 动画时长
                   options:// 动画过渡效果
                completion:^(BOOL finished) {

                    // 动画完成时的回调
                }];

③ 、过渡动画

②如何运用UIView block过渡动画?

我们只须要基于气象是变动单个视图的不可动画属性或视图行为要添加过渡动画还是给四个视图切换时添加过渡动画分选相应的办法就可以了。

(1)什么是连接动画?

第1篇说过了,类似。

连通动画(CATransition)同样是CAAnimation的三个子类,但它不像属性动画那样是一马平川地在七个属性值之间做动画,而是直白对全部图层做变更(即过渡动画不是本着图层的属性的,而是针对图层的,当然它能够用来做属性动画而不囿于于做属性动画,我们竟然能够在不改变图层或然不知情改变了图层什么东西的景况下直接给图层添加四个连着动画,相当于说过渡动画是给图层添的卡通片,只要有layer存在,大家别的机会任何景况都能给layer添加过渡动画,能够给layer添,也得以给view关联的layer添),即第三体现修改前的图层外观,然后经过1个连缀动画的职能变换来新的外观显示

三 、UIView的block动画应用举例

(2)怎样运用过渡动画?
  • 创办过渡动画
  • 设置好过渡动画的代办
  • 安装过渡动画类型, 过渡动画子类型, 过渡动画卡通速度及其余一些安装
  • 设置图层的新外观
  • 把过渡动画添加到layer上,过渡动画就起来履行了

连着动画类型(type):用来控制过渡动画的机能,有上边九种:

fade// 淡入淡出的效果(没有方向)
push// 新图层从一侧推入、旧图层从一侧推出来展示新外观效果
moveIn// 新图层从一侧推入来展示新外观效果、但旧图层没有从一侧推出
reveal// 旧图层从一侧推出来展示新外观效果、但新图层没有从一侧推入
oglFlip// 正面和背面的二维翻转效果
cube// 立方体翻转效果
pageCurl// 翻页效果
suckEffect// 收缩效果
rippleEffect// 水滴波纹效果(没有方向)

对接动画子类型如下(subType):用来支配过渡动画的方向,有上面各个,type里除了fade和rippleEffect没有动向之外,其它成效都有倾向

kCATransitionFromTop// 从底部开始过渡动画
kCATransitionFromLeft// 从左侧开始过渡动画
kCATransitionFromBottom// 从顶部开始过渡动画
kCATransitionFromRight// 从右侧开始过渡动画

转场动画缓冲曲线控制(timingFunction):有上面二种

kCAMediaTimingFunctionEaseInEaseOut// 动画慢进,逐渐加快,逐渐减慢,慢出
kCAMediaTimingFunctionEaseIn// 动画慢进,逐渐加快
kCAMediaTimingFunctionEaseOut// 动画逐渐减慢,慢出
kCAMediaTimingFunctionLinear// 动画匀速

可知layer显式动画的连通动画效果要比UIView
block过渡动画的法力多了过多,因而效果也会更丰富一些。

上边举个例证,类似第叁篇的,切换imageView的图形和label的文件,只然而是个水纹效果:

//
//  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 ()<CAAnimationDelegate>

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

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.customImageView = [[UIImageView alloc] init];
    self.customImageView.frame = CGRectMake(0, 64, kScreenWidth, kScreenWidth);
    self.customImageView.backgroundColor = [UIColor redColor];
    self.customImageView.image = [UIImage imageNamed:@"0.jpg"];
    [self.view addSubview:self.customImageView];

    self.label = [[UILabel alloc] init];
    self.label.frame = CGRectMake(0, kScreenWidth + 100, kScreenWidth, 30);
    self.label.text = @"奥黛丽·赫本";
    self.label.textColor = [UIColor blackColor];
    self.label.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:self.label];
}

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

    // 创建过渡动画
    CATransition *transition = [[CATransition alloc] init];

    // 设置好过渡动画的代理
    transition.delegate = self;

    // 设置过渡动画类型、子类型、时间曲线及其它一些设置
    transition.type = @"rippleEffect";
    transition.subtype = kCATransitionFromTop;
    transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    transition.duration = 3;

    // 设置图层的新外观
    NSInteger num = arc4random()%7;
    self.customImageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%ld.jpg", num]];
    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;
    }

    // 把过渡动画添加到layer上
    [self.customImageView.layer addAnimation:transition forKey:nil];
    [self.label.layer addAnimation:transition forKey:nil];
}

- (void)animationDidStart:(CAAnimation *)anim {

    NSLog(@"动画开始了");
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {

    NSLog(@"动画结束了");
}


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

@end

澳门新葡萄京娱乐 6

1.gif

壹 、UIView block基础动画
  • 让一条弹幕从右往左飘过去
    (清单1.1)

//
//  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
  • 漂完之后,我们改变下弹幕内容
    (清单1.2)

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

    [UIView animateWithDuration:5 animations:^{

        self.label.transform = CGAffineTransformMakeTranslation(-kScreenWidth, 0);
    } completion:^(BOOL finished) {

        self.label.text = @"你在哪儿,我就在哪儿!";
    }];
}
  • 作者们能够让弹幕匀速地飘过,而不是私下认可的easyInEasyOut
    (清单1.3)

- (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 = @"你在哪儿,我就在哪儿!";
    }];
}
  • 让弹幕弹一弹
    (清单1.4)

- (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 = @"你在哪儿,我就在哪儿!";
    }];
}

澳门新葡萄京娱乐 7

1.gif

肆 、什么情形下使用显示动画

针对基础动画:用UIView
block基础动画和layer的隐式动画就够了,layer的显式动画的底子动画也没多吗,用起来反而累赘。

针对首要帧动画:一般景况下利用UIView
block关键帧动画就能够,可是要是是要求一连关键帧的景观就需求运用layer的显式动画的重点帧动画。

针对过渡动画:一般景况下行使UIView
block过渡动画就可以,不过只要是内需更丰富动画效果的景色可以运用layer的显式动画的连通动画。

由此看来,大家权且还从未须要直接创设layer来做动画,开发中健康用UIView就足以了,UIView
block动画就隐瞒了,隐式动画和呈现动画也都是能够直接或直接地成效于view关联的layer的。

贰 、UIView block关键帧动画

接近FaceBook登录界面,登录失利那种输入框抖动的机能。若是使用基础动画的话,也许就得平移二回,再开叁个基础动画再平移3遍,得开好几个基础动画,关键帧动画的话就开四个动画就可以了,添关键帧就行了。

(清单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

澳门新葡萄京娱乐 8

1.gif

③ 、UIView block过渡动画
(1)给单个视图的不可动画属性或视图行为添加过渡动画
  • 切换imageView的图样和label的文书

(清单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

澳门新葡萄京娱乐 9

1.gif

  • 淡入淡出的机能添加view
    (清单1.7)

//
//  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

澳门新葡萄京娱乐 10

1.gif

(2)给多个视图切换时添加过渡动画
  • 比如说切换登录和注册视图(当然这几个也足以UIViewController的方法来替换,有同等的功力)

澳门新葡萄京娱乐 11

1.gif

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图