iOS学习——核心动画之Layer基础

1、CALayer是什么?

CALayer我们又称它叫做层。在每个UIView内部都有一个layer这样一个属性,UIView之所以能够显示,就是因为它里面有这个layer才具有显示的功能。我们可以通过操作CALayer对象,可以很方便地调整UIView的一些外观属性,可以给UIView设置阴影,圆角,边框等等...

2、如何操作layer改变UIView外观?

  2.1 设置阴影

//默认图层是有阴影的, 只不过,是透明的
_RedView.layer.shadowOpacity = ; //设置阴影的圆角
_RedView.layer.shadowRadius =; //设置阴影的颜色,把UIKit转换成CoreGraphics框架,用.CG开头
_RedView.layer.shadowColor = [UIColor blueColor].CGColor;

2.2.设置边框

//设置图层边框,在图层中使用CoreGraphics的CGColorRef
_RedView.layer.borderColor = [UIColor whiteColor].CGColor;
_RedView.layer.borderWidth = ;

2.3.设置圆角

//图层的圆角半径,圆角半径为宽度的一半, 就是一个圆
_RedView.layer.cornerRadius = ;

3、如何操作layer改变UIImageView的外观?

//设置图形边框
_imageView.layer.borderWidth = ;
_imageView.layer.borderColor = [UIColor whiteColor].CGColor; //设置图片的圆角半径,必须要进行第二步的裁剪,超出裁剪区域的部分全部裁剪掉
_imageView.layer.cornerRadius = ;
_imageView.layer.masksToBounds = YES; 

注意:设置图片的圆角时,除了设置圆角半径,还必须要进行第二步的裁剪,设置masksToBounds为yes。这是因为UIImageView当中Image并不是直接添加在层上面的,这是添加在layer当中的contents里。UIImageView中是UIView的主layer上添加了一个次layer(用来绘制contents),我们设置边框的是主layer,但是次layer在上变,不会有任何的影响,所以当我们调用切割语句的时候,超出边框意外的都被切割了!!

我们设置层的所有属性它只作用在层上面,对contents里面的东西并不起作用,所以如果我们不进行裁剪,我们是看不到图片的圆角效果的。想要让图片有圆角的效果,就必须把masksToBounds这个属性设为YES,当设为YES,把就会把超过根层以外的东西都给裁剪掉。

4、layer的 CATransform3D属性变换

  UIView和Layer都有transform属性,但是他们的所属有区别,类型也有区别

1.picView.transform是二维的属性,是CGAffineTransform类型
2.picView.layer.transform是layer级别的三维属性,是CATransform3D类型的,当然也可以做二维的事情,只有旋转的时候才可以看出3D的效果.

//旋转  x,y,z 分别代表x,y,z轴.
CATransform3DMakeRotation(M_PI, , , ); //平移
CATransform3DMakeTranslation(x,y,z) //缩放
CATransform3DMakeScale(x,y,z);

  属性设置有三种方法

//1.直接使用基本的三维赋值方法
picView.layer.transform = CATransform3DMakeScale(, 2.5, ); //2.使用KVC将CATransform3DMakeScale生成的对象给layer
NSValue *value = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI, , , )];
[picView.layer setValue:value forKeyPath:@"transform.scale"]; //3.使用快捷方法设置属性
[picView.layer setValue:@ forKeyPath: "transform.scale.y"];

什么时候用KVC?

当需要做一些快速缩放,平移,二维的旋转时用KVC。后面forKeyPath属性值不是乱写的,苹果文档当中给了相关的属性.

比如: [_imageView.layer setValue:@0.5 forKeyPath:@"transform.scale"];

5、如何自定义Layer ?

  自定义CALayer的方式创建UIView的方式非常相似。

//创建
CALayer *layer = [CALayer layer];
//设置尺寸和位置
layer.frame = CGRectMake(, , , );
//设置背景
layer.backgroundColor = [UIColor redColor].CGColor;
//给layer设置图片.
layer.contents = (id)[UIImage imageNamed:@"image001"].CGImage;
//加载绘制
[self.view.layer addSublayer:layer];

6、为什么要使用CGImageRef、CGColorRef?

  为了保证可移植性,QuartzCore不能使用UIImage、UIColor,只能使用CGImageRef、CGColorRef

7、UIView和CALayer都能够显示东西,该怎样选择?

  在明白要怎么选择之前,我们先了解一下UIView和layer的不同点:

    • 在iOS中看的见,摸得着的都是UIView,例如一个按钮,UITextField,UILable等等,都是UIView
    • UIView之所以能够显示在屏幕上,是试音UIView中有一个图层
    • 在创建UIView的时候,系统会自动创建一个CALayer在其中,用于显示东西,可以通过view.layer来去获取图层属性
    • 当UIView要去显示的时候,先去调用drawRect方法,将要绘制的东西绘制到图层上,然后拷贝图层,完成了UIView的显示
    • UIView只有交互的功能,没有显示的功能
    • CALayer只要显示的功能,没有交互的功能
    • UIView可以做一些简单的动画,例如:平移,拉伸,旋转
    • 一些比较高端的动画,都是直接操作CALayer的,可以制作3D动画
    • 使用CALayer,可以直接操作显示的东西,例如阴影,圆角,边框等

所以,对比CALayer,UIView多了一个事件处理的功能。也就是说,CALayer不能处理用户的触摸事件,而UIView可以。

如果显示出来的东西需要跟用户进行交互的话,用UIView;

  如果不需要跟用户进行交互,用UIView或者CALayer都可以,CALayer的性能会高一些,因为它少了事件处理的功能,更加轻量级。

8、position和anchorPoint?

  position和anchorPoint是CAlayer的两个属性,我们以前修改一个控件的位置都是通过Frame的方式进行修改。现在CALayer则是通过position和anchorPoint属性也能够修改控件的位置,

这两个属性是配合使用的。

  position:它是用来设置当前的layer在父控件当中的位置的,默认它的坐标原点,以父控件的左上角为(0.0)点。

  anchorPoint:锚点,就是把锚点定到position所指的位置。它是决点CALayer身上哪一个点会在position属性所指的位置,anchorPoint它是以当前的layer左上角为原点(0.0),它的取值范围是0~1,它的默认在中间也就是(0.5,0.5)的位置。

  两者结合使用,想要修改某个控件的位置,我们可以设置它的position点。设置完毕后,layer身上的anchorPoint会自动定到position所在的位置。

//下面两行代码就是设置views的 正中间 坐标(200,200)
_views.layer.position = CGPointMake(, );
_views.layer.anchorPoint = CGPointMake(0.5, 0.5); //下面两行代码就是设置views的 左上角 坐标(200,200)
_views.layer.position = CGPointMake(, );
_views.layer.anchorPoint = CGPointMake(, ); //下面两行代码就是设置views的 右下角 坐标(200,200)
_views.layer.position = CGPointMake(, );
_views.layer.anchorPoint = CGPointMake(, );

9、隐式动画

9.1 什么是隐式动画?

了解什么是隐式动画,要先了解是什么根层和非根层:

    • 根层:UIView内部自动关联着的那个layer我们称它是根层.
    • 非根层:自己手动创建的层,称为非根层.

隐式动画就是当对非根层的部分属性进行修改时, 它会自动的产生一些动画的效果,我们称这个默认产生的动画为隐式动画.

9.2 如何取消隐式动画?

首先要了解动画底层是怎么做的,动画的底层是包装成一个事务来进行的。

什么是事务? 很多操作绑定在一起,当这些操作执行完毕后,才去执行下一个操作.

//开启事务
[CATransaction begin]; //设置事务没有动画
[CATransaction setDisableActions:YES]; //设置动画执行的时长
[CATransaction setAnimationDuration:]; //提交事务
[CATransaction commit];

10、时钟效果

10.1 搭建界面

  界面上时针、分针、秒针不需要与用户进行交互,所以都可以使用layer方式来做,具体时间可以用用一张圆形图片来显示,然后在这个imageView的layer中进行时针、分针和秒针的绘制。

  做之前要观察时针在做什么效果。是根据当前的时间,绕着表盘的中心点进行旋转.

  要了解一个非常重要的知识点,无论是旋转,缩放它都是绕着锚点进行的。要想让时针、分针、称针显示的中间,还要绕着中心点进行旋转,那就要设置它的position和anchorPoint两个属性.

//添加秒针
- (void)addSecond{
//创建秒针
CALayer *layer = [CALayer layer];
_secondL = layer;
//设置宽高
layer.bounds = CGRectMake(, , , );
//设置锚点为秒针的 x轴中心,y轴最右端,该锚点的位置是时钟图片的正中心
layer.anchorPoint = CGPointMake(0.5, );
layer.position = CGPointMake(_clockView.bounds.size.width * 0.5, _clockView.bounds.size.height * 0.5);
//设置秒针的颜色
layer.backgroundColor = [UIColor redColor].CGColor;
//将秒针的layer添加到时钟图片的layer中
[_clockView.layer addSublayer:layer]; } //时针、分针的添加方式类似,只是设置的宽高有点区别,不再贴出来

10.2 让秒针开始旋转.

//角度转换成弧度
#define angle2Rad(angle) ((angle) / 180.0 * M_PI) //每一秒 秒针 旋转6度
#define perSecondA 6
//每一分 分针 旋转
#define perMinA 6
//每一小时 时针 旋转30
#define perHourA 30
//第一分钟 时针 旋转0.5
#define perMinHour 0.5 //每一秒调用一次
- (void)timeChage{ NSCalendar *calendar = [NSCalendar currentCalendar];
//components日历单元:年,月,日,时,分,秒
//fromDate:从哪个时间开始取
NSDateComponents *cmp = [calendar components:NSCalendarUnitSecond | NSCalendarUnitMinute | NSCalendarUnitHour fromDate:[NSDate date]];
//获取当前时间的时 分 秒
NSInteger curSecond = cmp.second;
NSInteger curMinute = cmp.minute;
NSInteger curHour = cmp.hour; //秒针 旋转多少度. 当前的秒数乘以每秒转多少度.
CGFloat angle = curSecond * perSecondA;
self.secondL.transform = CATransform3DMakeRotation(angle2Rad(angle), , , );
//分针 旋转多少度. 当前的分钟乘以每分转多少度.
CGFloat minuteA = curMinute * perMinA;
self.minuteL.transform = CATransform3DMakeRotation(angle2Rad(minuteA), , , ); //时针旋转的度数应该是 多少小时对应的度数+分钟对应的时针旋转的度数
CGFloat hourA = curHour * perHourA + curMinute * perMinHour;
self.hourL.transform = CATransform3DMakeRotation(angle2Rad(hourA), , , );
}

10.3 将布局和旋转进行组合

每过一秒,我们的秒针就需要变化位置,所以我们我们需要设置一个定时器,在开始时每秒执行一次旋转布局绘制。

- (void)viewDidLoad {
[super viewDidLoad];
//添加时针 分针 秒针
[self addHour]; [self addMinue]; [self addSecond]; //添加定时器,每秒进行绘制
[NSTimer scheduledTimerWithTimeInterval: target:self selector:@selector(timeChage) userInfo:nil repeats:YES]; //绘制
[self timeChage]; }

iOS学习——核心动画之Layer基础的更多相关文章

  1. iOS学习——核心动画

    iOS学习——核心动画 1.什么是核心动画 Core Animation(核心动画)是一组功能强大.效果华丽的动画API,无论在iOS系统或者在你开发的App中,都有大量应用.核心动画所在的位置如下图 ...

  2. IOS QuartzCore核心动画框架

    IOS QuartzCore核心动画框架 核心动画框架 使用核心动画需要引入的框架:#import CALayer: CoreAnimation CALayer就是UIView上的图层,很多的CALa ...

  3. ios开发之核心动画四:核心动画-Core Animation--CABasicAnimation基础核心动画

    #import "ViewController.h" @interface ViewController () @property (weak, nonatomic) IBOutl ...

  4. iOS:核心动画的详解介绍:CAAnimation(抽象类)及其子类

    核心动画的详解介绍:CAAnimation(抽象类)   1.核心动画基本概念 Core Animation是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍! 使用它 ...

  5. iOS之核心动画(Core Animation)

      Core Animation,中文翻译为核心动画,它是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍.也就是说,使用少量的代码就可以实现非常强大的功能. Core ...

  6. iOS之核心动画

    .将动画的所有方法封装到一个类里面 MyCAHelper.h #import <Foundation/Foundation.h> #import <QuartzCore/Quartz ...

  7. iOS CoreAnimation 核心动画

    一 介绍 一组非常强大的动画处理API 直接作用在CALAyer上,并非UIView(UIView动画) CoreAnimation是所有动画的父类,但是不能直接使用,应该使用其子类 属性: dura ...

  8. iOS:核心动画之基本动画CABasicAnimation

    基本动画,是CAPropertyAnimation的子类 属性说明: fromValue:keyPath相应属性的初始值 toValue:keyPath相应属性的结束值 动画过程说明: 随着动画的进行 ...

  9. iOS开发-核心动画随笔

    核心动画可以让View旋转,缩放,平移(主要是操作View的layer(层)属性)但是核心动画改变的位置不是真实的位置,一切都是假象所以有时候要用到其他动画,如UIView本来封装的动画,还有定时器 ...

随机推荐

  1. kettle基础概念的学习

    参考书籍:Pentaho Kettle Solutions中文版.由于最近不断的使用kettle,随着不断深入使用,遇到的问题越来越多,发现脑子那点货根本不够用,所以根据阅读把一些概念记录一下,方便自 ...

  2. Python 官方文档解读(2):threading 模块

    使用 Python 可以编写多线程程序,注意,这并不是说程序能在多个 CPU 核上跑.如果你想这么做,可以看看关于 Python 并行计算的,比如官方 Wiki. Python 线程的主要应用场景是一 ...

  3. 基于ASP.NET MVC 下的Extjs的Combbox加载速率问题,终于解决啦:)

    在实际的开发项目中,自己遇到一个让自己苦恼很久的问题,一直也未解决,先简单介绍一下这个问题吧.当在表单里有多个combbox的时候(表单中的combbox是经过封装的控件,从后台请求同一个方法获取数据 ...

  4. pwn学习之三

    whctf2017的一道pwn题sandbox,这道题提供了两个可执行文件加一个libc,两个可执行文件是一个vuln,一个sandbox,这是一道通过沙盒去保护vuln不被攻击的题目. 用ida打开 ...

  5. php 设计模式(转)

    PhpDesignPatterns [PHP 中的设计模式] 一. Introduction[介绍] 设计模式:提供了一种广泛的可重用的方式来解决我们日常编程中常常遇见的问题.设计模式并不一定就是一个 ...

  6. idea通过mapper快速定位到xml文件

    1.点击File找到设置(Settings) 2.点击Plugins下的 Browse respositories 3.在搜索栏搜索mybatis ,选中 Free Mybatis plugin——i ...

  7. github-新建文件夹

    1,进入仓库“ sstruggle.github.io ”中,在该仓库页面中找到“ Create new file ”,如图: 2,在创建新文件页面,输入“ js/ ”,github默认为是一个文件夹 ...

  8. Java中死锁的定位与修复

    死锁应该可以说是并发编程中比较常见的一种情况,可以说如果程序产生了死锁那将会对程序带来致命的影响:所以排查定位.修复死锁至关重要: 我们都知道死锁是由于多个对象或多个线程之间相互需要对方锁持有的锁而又 ...

  9. java中的HMAC-SHA1加密

    public class Sha1Util { private static final String MAC_NAME = "HmacSHA1"; private static ...

  10. CefSharp Cookie独立 GetGlobalCookieManager

    可以实现:  登陆多个京东站点,而京东各个账号互不影响. 可以完全实现Cookie独立,Cache独立. Demo用VS2017开发,C# ,NET4.5 没错,稍加改造就可以用来刷单.有Demo,有 ...