UIView动画

一般来说,对于UIView的动画,大概分为UIView的仿射变换,基于CA和它的子类的动画,以及CG相关的动画。

动画的形式一般为平移,缩放,旋转,翻转,一种或多种组合。设置动画变换常用的属性.frame.transform,因此常被称为

  1. frame动画
  2. transform动画

使用这两种动画模式,只需要在apple提供的动画api中适当的添加动画后的frame和transform,并设置好动画时长,即可达到动画过度的效果。但是使用frame的局限性很强,使用平移和缩放还好,旋转则需要使用比较复杂的矩阵计算公式,才能得到旋转后的frame,所以只适合实现最简单的平移和缩放的动画。

所以本章主要的还是讨论transform动画

动画的语法api

动画的语法常用的有两种方式

  1. UIView的block方式

     [UIView animateWithDuration:2.0 animations:^{
         view.transform = transform;
     }];
    
  2. UIView的begin-commit方式

    - (void)transformLeftToRightAndScale {
        UIView *view = [self getView];
        CGRect start = CGRectMake(10, 64 + 10 + 2 * (50 + 10), 50, 50);
        view.frame = start;
        [self.view addSubview:view];
        
        CGAffineTransform bigTransform = CGAffineTransformMakeScale(1.2, 1.2);
        
        CGFloat fx = BoundW - CGRectGetWidth(view.frame) - 10 - 10; // 沿着X方向平移
        CGFloat fy = - 2 * (50 + 10); // 沿着Y方向平移
        CGAffineTransform moveTransform = CGAffineTransformMakeTranslation(fx, fy);
        
        CGAffineTransform rotate = CGAffineTransformMakeRotation(M_PI);
        
        [UIView beginAnimations:@"move" context:nil];
        [UIView setAnimationDelegate:self];
        [UIView setAnimationDuration:2.0];
        
        [view setTransform:CGAffineTransformConcat(rotate, CGAffineTransformConcat(bigTransform, moveTransform))];
        
        [UIView commitAnimations];
    }

仿射变换,仿射变换的两种类型--二维和三维

仿射变换分为二维的仿射变换和三维的仿射变换,对应的api分别为CGAffineTransformCATransform3D.

CGAffineTransform

CGAffineTransform适用于平移,缩放,旋转,在二维空间进行操作。api为animationView.transform = transform。来先看一下CGAffineTransform的数据结构。

struct CGAffineTransform {
    CGFloat a, b, c, d;
    CGFloat tx, ty;
};

CGAffineTransform使用一个结构体进行封装,本质上表达的是一个3*3的矩阵。由于第三列始终是(0,0,1),因此数据结构仅包含前两列的值。

CGAffineTransform矩阵.png

CGAffineTransform从概念上讲,仿射变换将表示图形中每个点(x,y)的行向量乘以该矩阵,从而生成表示对应点(x',y')的向量:

image.png

给定3乘3矩阵,以下等式用于将一个坐标系中的点(x,y)变换为另一个坐标系中的合成点(x',y')

image.png

所以当两个仿射进行连接,本质上是两个仿射变换的矩阵乘积

矩阵数学计算公式 理解矩阵乘法

矩阵计算公式.png

CGAffineTransform的相关api

最具体的还是参考 CGAffineTransform文档

  1. 创建仿射变换矩阵

     CGAffineTransform CGAffineTransformMake(CGFloat a, CGFloat b, CGFloat c, CGFloat d, CGFloat tx, CGFloat ty); //返回根据您提供的值构造的仿射变换矩阵
    
     CGAffineTransform CGAffineTransformMakeRotation(CGFloat angle); //返回根据您提供的旋转值构造的仿射变换矩阵。
    
     CGAffineTransform CGAffineTransformMakeScale(CGFloat sx, CGFloat sy); //返回由您提供的缩放值构造的仿射变换矩阵。
    
     CGAffineTransform CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty); //返回根据您提供的转换值构造的仿射变换矩阵
    
  2. 修改仿射变换

    CGAffineTransform CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty); // 通过修改现有仿射变换而构造的仿射变换矩阵。
    
    CGAffineTransformScale // 返回通过缩放现有仿射变换而构造的仿射变换矩阵
    
    CGAffineTransformRotate // 返回通过旋转现有仿射变换构造的仿射变换矩阵
    
    CGAffineTransformInvert // 返回通过反转现有仿射变换而构造的仿射变换矩阵
    
    CGAffineTransformConcat // 返回通过组合两个现有仿射变换而构造的仿射变换矩阵
  1. 应用仿射变换

     CGPoint CGPointApplyAffineTransform(CGPoint point, CGAffineTransform t); // 将指定的仿射变换应用于现有点所产生的新点
     
     CGSize CGSizeApplyAffineTransform(CGSize size, CGAffineTransform t); // 通过将指定的仿射变换应用于现有大小而产生的新大小
     
     CGRect CGRectApplyAffineTransform(CGRect rect, CGAffineTransform t); // 变换后的矩形
    

CGAffineTransformConcat

组合两个已存在的仿射变换,数学本质上是两个矩阵进行乘积。

CGAffineTransform CGAffineTransformConcat(CGAffineTransform t1, CGAffineTransform t2);

CATransform3D

CATransform3D变换矩阵用于旋转,缩放,平移,倾斜和投影图层内容,适用于二维和三维空间进行变换。api为animationView.layer.transform = transform。来先看一下CATransform3D的数据结构。

struct CATransform3D
{
  CGFloat m11, m12, m13, m14;
  CGFloat m21, m22, m23, m24;
  CGFloat m31, m32, m33, m34;
  CGFloat m41, m42, m43, m44;
};

CATransform3D是一4*4的矩阵,同样表示一个点的映射关系 iOS核心动画:高级技巧(2014)

image.png

CATransform3D操作api

//还原
 CATransform3DIdentity

//位移3D仿射  ==> (CGFloat tx, CGFloat ty, CGFloat tz)
CATransform3DMakeTranslation
CATransform3DTranslate        
//旋转3D仿射 ==> (CGFloat angle, CGFloat x, CGFloat y, CGFloat z)
CATransform3DMakeRotation
CATransform3DRotate  
//缩放3D仿射 ==>  (CGFloat angle, CGFloat x, CGFloat y, CGFloat z)
CATransform3DMakeScale
CATransform3DScale
//叠加3D仿射效果
CATransform3DConcat    
//仿射基础3D方法,可以直接做效果叠加
CGAffineTransformMake (sx,shx,shy,sy,tx,ty)
//检查是否有做过仿射3D效果  == ((CATransform3D t))
CATransform3DIsIdentity(transform)
//检查2个3D仿射效果是否相同
CATransform3DEqualToTransform(transform1,transform2)
//3D仿射效果反转(反效果,比如原来扩大,就变成缩小)
CATransform3DInvert(transform)

带有Make的为构建api,即创建一个CATransform3D类型的仿射变换。没有带Make一般为修改给定的仿射变换,并返回修改后的仿射变换。如:

CATransform3D CATransform3DMakeTranslation(CGFloat tx, CGFloat ty, CGFloat tz); // 返回一个设定了转移的仿射变换

CATransform3D CATransform3DTranslate(CATransform3D t, CGFloat tx, CGFloat ty, CGFloat tz); // 修改给定的`CATransform3D t`

CATransform3DConcat

类似的,和CGAffineTransformConcat一样,用于连接两个仿射变换,返回一个连接后的仿射变换。

CATransform3D CATransform3DConcat(CATransform3D a, CATransform3D b); // Concatenates b to a and returns the result: t = a * b.

结尾

下一章节,可以看看Core Animation中的动画实现。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,264评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,549评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,389评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,616评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,461评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,351评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,776评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,414评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,722评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,760评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,537评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,381评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,787评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,030评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,304评论 1 252
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,734评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,943评论 2 336

推荐阅读更多精彩内容