iOS Core Animation Advanced Techniques-变换

上四章节:

  1. 图层树
  2. 图层的寄宿图
  3. 图层几何学
  4. 图层视觉效果

这篇随笔主要介绍有关图层变换。

  • 变换:

    • 对图层旋转,摆放或者扭曲的CGAffineTransform,可以将扁平物体转换成三维空间对象的CATransform3D
  • 仿射(图层中平行的两条线在变换之后任然保持平行)变换:
    • CGAffineTransform属性(仅对2D变换有效)

      • 用于在二维空间做旋转,缩放与平移

CALayer的affineTransform属性就是一个CGAffineTransform类型对象,UIView对应的属性为transform属性
CALayer的transform属性是一个CATransform3D类型而不是CGAffineTransform类型
系统提供创建CGAffineTransform实例对象的主要3个方法:

    1. CGAffineTransformMakeRotation(CGFloat angle);//旋转
    2. CGAffineTransformMakeScale(CGFloat sx,CGFloat sy);//缩放
    3. CGAffineTransformMakeTranslation(CGFloat tx,CGFloat ty);//平移
      • 使用例子:
      • CGAffineTransform transform=CGAffineTransformMakeRotation(M_PI_4);//iOS的变换函数使用弧度而不是角度作为单位
      • myView.layer.affineTransform=transform;
  • 混合变换:

在一个变换的基础上做更深层次的变换,如做一个既要缩放又要旋转的变换,使用以下3个函数:

    1. CGAffineTransformRotate(CGAffineTransform t, CGFloat angle)
    2. CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy)
    3. CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty)
    • 实现过程中一般先生成一个CGAffineTransform类型的空值,通过CGAffineTransformIdentity()函数获取
    • 如果需要混合两个已经存在的变换矩阵,就可以使用如下方法,在两个变换的基础上创建一个新的变换:
    • CGAffineTransform totalAffineTransform=CGAffineTransformConcat(CGAffineTransform t1, CGAffineTransform t2);
      • 使用例子:
      • //实现先缩小50%,再旋转30度,最后向右移动200个像素
      • CGAffineTransform transform=CGAffineTransformIdentity;
      • transform=CGAffineTransformScale(transform,0.5,0.5);
      • transform=CGAffineTransformRotate(transform, M_PI / 180.0 * 30.0);
      • transform = CGAffineTransformTranslate(transform, 200, 0);
      • myView.layer.affineTransform=transform;

注意:

当你按顺序做了变换,上一个变换的结果将会影响之后的变换,所以200像素的向右平移同样也被旋转了30度,缩小了50%,所以它实际上是斜向移动了100像素

意味着变换的顺序会影响最终的结果,也就是说旋转之后的平移和平移之后的旋转结果可能不同

  • 剪切变换:

如一个矩形变成了一个平行四边形(倾斜)

    • 使用例子:
    • CGAffineTransform transform=CGAffineTransformIdentity;
    • transform.c=-1.0f;
    • transform.b=0f;
    • myView.layer.affineTransform=transform;
  • 3D变换:

    • transform属性

      • 是一个CATransform3D类型,UIView上没有对应属性
      • CG前缀属于Core Graphics框架(2D绘图API),CGAffineTransform仅对2D变换有效
      • 系统提供创建CATransform3D实例对象的主要3个方法:(对比Core Graphics的2D函数多出z轴参数)
      1. CATransform3DMakeRotation(CGFloat angle, CGFloat x, CGFloat y, CGFloat z);
      2. CATransform3DMakeScale(CGFloat sx, CGFloat sy, CGFloat sz) ;
      3. CATransform3DMakeTranslation(Gloat tx, CGFloat ty, CGFloat tz);
        • 使用例子:
        • CATransform3D transform=CATransform3DMakeRotation(M_PI_4,0,1,0);
        • myView.layer.transform=transform;
        • 注意:若不设置透视投影效果,视图看起来没有斜向视角效果
  • 透视投影:
    • CATransform3D的m34属性用来做透视

      • m34默认值为0
      • 通过设置m34为-1.0/d应用透视效果,d代表视角与事物距离,通常设置为500-1000
      • 使用例子:
      • CATransform3D transform=CATransform3DIdentity;
      • transform.m34=-1.0/500.0;
      • transform=CATransform3DRotate(transform,M_PI_4,0,1,0);
      • myView.layer.transform=transform;
  • sublayerTransform属性:
    • 是一个CATransform3D类型,设置该属性会影响到所有的子图层,一次性对包含这些图层的容器做变换,所有子图层自动继承该变换方法

      • 使用例子:
      • [myContainerView addSubView:myView1];
      • [myContainerView addSubView:myView2];
      • CATransform3D perspective=CATransform3DIdentity;
      • perspective.m34=-1.0/500.0;
      • myContainerView.layer.sublayerTransform=perspective;
      • CATransform3D transform1 = CATransform3DMakeRotation(M_PI_4, 0, 1, 0);
      • myView1.layer.transform=transform1;
      • CATransform3D transform2=CATransform3DMakeRotation(-M_PI_4,0,1,0);
      • myView2.layer.transform=transform2;
  • 背面:
    • 默认图层是双面绘制,反面显示的是正面的一个镜像图片(不需要的时候会造成资源浪费)
    • 通过设置CALayer上的doubleSided属性为NO不绘制背面寄宿图内容
  • 扁平化图层:
    • 内部图层相对外部图层做了相反的变换,那么这两个变换将被相互抵消(绕Z轴做的变换);

      • 如:
      • CATransform3D outer = CATransform3DMakeRotation(M_PI_4, 0, 0, 1);
      • outerView.layer.transform = outer;
      • CATransform3D inner = CATransform3DMakeRotation(-M_PI_4, 0, 0, 1);
      • innerView.layer.transform = inner;
    • 若不是绕Z轴做的变换,而是Y轴,那么由于每个图层的3D场景是扁平化的,也就是有图层模拟出来的立体场景,倾斜时,子图层仍是被扁平贴在父视图上,父子层面永远平行,此时两相反变化没有呈现抵消效果
      • 如:
      • CATransform3D outer = CATransform3DIdentity;
      • outer.m34 = -1.0 / 500.0;
      • outer = CATransform3DRotate(outer, M_PI_4, 0, 1, 0);
      • self.outerView.layer.transform = outer;
      • CATransform3D inner = CATransform3DIdentity;
      • inner.m34 = -1.0 / 500.0;
      • inner = CATransform3DRotate(inner, -M_PI_4, 0, 1, 0);
      • self.innerView.layer.transform = inner;
  • 固体对象:
    • 固态的3D对象,实际上是一个技术上所谓的空洞对象,但整体以固态呈现
    • 用几面图层经位移旋转拼凑而成的固体,如使用例子:
      • @interface ViewController ()
      • @property (nonatomic, weak) IBOutlet UIView *containerView;
      • @property (nonatomic, strong) IBOutletCollection(UIView) NSArray *faces;
      • @end
      • @implementation ViewController
      • - (void)addFace:(NSInteger)index withTransform:(CATransform3D)transform{
      • //get the face view and add it to the container
      • UIView *face = self.faces[index];
      • [self.containerView addSubview:face];
      • //center the face view within the container
      • CGSize containerSize = self.containerView.bounds.size;
      • face.center = CGPointMake(containerSize.width / 2.0, containerSize.height / 2.0);
      • // apply the transform
      • face.layer.transform = transform;
      • }
      • - (void)viewDidLoad{
      • [super viewDidLoad];
      • //set up the container sublayer transform
      • CATransform3D perspective = CATransform3DIdentity;
      • perspective.m34 = -1.0 / 500.0;
      • perspective = CATransform3DRotate(perspective, -M_PI_4, 1, 0, 0);
      • perspective = CATransform3DRotate(perspective, -M_PI_4, 0, 1, 0);
      • self.containerView.layer.sublayerTransform = perspective;
      • //add cube face 1
      • CATransform3D transform = CATransform3DMakeTranslation(0, 0, 100);
      • [self addFace:0 withTransform:transform];
      • //add cube face 2
      • transform = CATransform3DMakeTranslation(100, 0, 0);
      • transform = CATransform3DRotate(transform, M_PI_2, 0, 1, 0);
      • [self addFace:1 withTransform:transform];
      • //add cube face 3
      • transform = CATransform3DMakeTranslation(0, -100, 0);
      • transform = CATransform3DRotate(transform, M_PI_2, 1, 0, 0);
      • [self addFace:2 withTransform:transform];
      • //add cube face 4
      • transform = CATransform3DMakeTranslation(0, 100, 0);
      • transform = CATransform3DRotate(transform, -M_PI_2, 1, 0, 0);
      • [self addFace:3 withTransform:transform];
      • //add cube face 5
      • transform = CATransform3DMakeTranslation(-100, 0, 0);
      • transform = CATransform3DRotate(transform, -M_PI_2, 0, 1, 0);
      • [self addFace:4 withTransform:transform];
      • //add cube face 6
      • transform = CATransform3DMakeTranslation(0, 0, -100);
      • transform = CATransform3DRotate(transform, M_PI, 0, 1, 0);
      • [self addFace:5 withTransform:transform];
      • }
      • @end
  • 光亮与阴影:
    • 可以通过改变每个面的背景颜色或者直接用带光亮效果的图片来调整
    • 用GLKit框架来做向量的计算(略)
  • 点击事件:
    • 点击事件的处理由视图在父视图中的顺序决定的,并不是3D空间中的Z轴顺序
    • 当立体显示视图时因响应顺序问题导致事件拦截的问题,解决方案:
    • 把除了表面的其他视图userInteractionEnabled属性都设置成NO来禁止事件传递。
    • 或者简单通过代码把视图覆盖在拦截了事件的视图上。
时间: 2024-10-12 05:44:14

iOS Core Animation Advanced Techniques-变换的相关文章

iOS Core Animation Advanced Techniques(二):视觉效果和变换

四)视觉效果 嗯,园和椭圆还不错,但如果是带圆角的矩形呢? 我们现在能做到那样了么? 史蒂芬·乔布斯 我们在第三章『图层几何学』中讨论了图层的frame,第二章『寄宿图』则讨论了图层的寄宿图.但是图层不仅仅可以是图片或是颜色的容器:还有一系列内建的特性使得创造美丽优雅的令人深刻的界面元素成为可能.在这一章,我们将会探索一些能够通过使用CALayer属性实现的视觉效果. 圆角 圆角矩形是iOS的一个标志性审美特性.这在iOS的每一个地方都得到了体现,不论是主屏幕图标,还是警告弹框,甚至是文本框.按

iOS Core Animation Advanced Techniques(一):图层树、寄宿图以及图层几何学

(一)图层的树状结构 巨妖有图层,洋葱也有图层,你有吗?我们都有图层 -- 史莱克 Core Animation其实是一个令人误解的命名.你可能认为它只是用来做动画的,但实际上它是从一个叫做Layer Kit这么一个不怎么和动画有关的名字演变而来,所以做动画这只是Core Animation特性的冰山一角. Core Animation是一个复合引擎,它的职责就是尽可能快地组合屏幕上不同的可视内容,这个内容是被分解成独立的图层,存储在一个叫做图层树的体系之中.于是这个树形成了UIKit以及在iO

IOS Core Animation Advanced Techniques的学习笔记(四)

第五章:Transforms Affine Transforms CGAffineTransform是二维的 Creating a CGAffineTransform 主要有三种变化方法 旋转: CGAffineTransformMakeRotation(CGFloat angle) 缩放: CGAffineTransformMakeScale(CGFloat sx, CGFloat sy) 移动: CGAffineTransformMakeTranslation(CGFloat tx, CGF

iOS Core Animation Advanced Techniques(四):隐式动画和显式动画

隐式动画 按照我的意思去做,而不是我说的. -- 埃德娜,辛普森 我们在第一部分讨论了Core Animation除了动画之外可以做到的任何事情.但是动画师Core Animation库一个非常显著的特性.这一章我们来看看它是怎么做到的.具体来说,我们先来讨论框架自动完成的隐式动画(除非你明确禁用了这个功能). 事务 Core Animation基于一个假设,说屏幕上的任何东西都可以(或者可能)做动画.动画并不需要你在Core Animation中手动打开,相反需要明确地关闭,否则他会一直存在.

iOS Core Animation Advanced Techniques(六): 基于定时器的动画和性能调优

基于定时器的动画 我可以指导你,但是你必须按照我说的做. -- 骇客帝国 在第10章“缓冲”中,我们研究了CAMediaTimingFunction,它是一个通过控制动画缓冲来模拟物理效果例如加速或者减速来增强现实感的东西,那么如果想更加真实地模拟 物理交互或者实时根据用户输入修改动画改怎么办呢?在这一章中,我们将继续探索一种能够允许我们精确地控制一帧一帧展示的基于定时器的动画. 定时帧 动画看起来是用来显示一段连续的运动过程,但实际上当在固定位置上展示像素的时候并不能做到这一点.一般来说这种显

iOS Core Animation Advanced Techniques(五):图层时间和缓冲

图层时间 时间和空间最大的区别在于,时间不能被复用 -- 弗斯特梅里克 在上面两章中,我们探讨了可以用CAAnimation和它的子类实现的多种图层动画.动画的发生是需要持续一段时间的,所以计时对整个概念来说至关重要.在这一章中,我们来看看CAMediaTiming,看看Core Animation是如何跟踪时间的. CAMediaTiming协议 CAMediaTiming协议定义了在一段动画内用来控制逝去时间的属性的集合,CALayer和CAAnimation都实现了这个协议,所以时间可以被

iOS Core Animation Advanced Techniques(三):专用图层

到目前为止,我们已经探讨过CALayer类了,同时我们也了解到了一些非常有用的绘图和动画功能.但是Core Animation图层不仅仅能作用于图片和颜色而已.本章就会学习其他的一些图层类,进一步扩展使用Core Animation绘图的能力. CAShapeLayer 在第四章『视觉效果』我们学习到了不使用图片的情况下用CGPath去构造任意形状的阴影.如果我们能用同样的方式创建相同形状的图层就好了. CAShapeLayer是一个通过矢量图形而不是bitmap来绘制的图层子类.你指定诸如颜色

IOS Core Animation Advanced Techniques的学习笔记(五)

第六章:Specialized Layers   类别 用途 CAEmitterLayer 用于实现基于Core Animation粒子发射系统.发射器层对象控制粒子的生成和起源 CAGradientLayer 用于绘制一个颜色渐变填充图层的形状(所有圆角矩形边界内的部分) CAEAGLLayer/CAOpenGLLayer 用于设置需要使用OpenGL ES(iOS)或OpenGL(OS X)绘制的内容与内容储备. CAReplicatorLayer 当你想自动生成一个或多个子层的拷贝.复制器

IOS Core Animation Advanced Techniques的学习笔记(一)

转载. Book Description Publication Date: August 12, 2013 Core Animation is the technology underlying Apple’s iOS user interface. By unleashing the full power of Core Animation, you can enhance your app with impressive 2D and 3D visual effects and creat

iOS Core Animation Advanced Techniques(七):高效绘图、图像IO以及图层性能

高效绘图不必要的效率考虑往往是性能问题的万恶之源. ——William Allan Wulf 在第12章『速度的曲率』我们学习如何用Instruments来诊断Core Animation性能问题.在构建一个iOS app的时候会遇到很多潜在的性能陷阱,但是在本章我们将着眼于有关绘制的性能问题. 软件绘图 术语绘图通常在Core Animation的上下文中指代软件绘图(意即:不由GPU协助的绘图).在iOS中,软件绘图通常是由Core Graphics框架完成来完成.但是,在一些必要的情况下,