IOS控件动画的一种通用方法

最近在做一个垂直弹幕控件 , 在做控件动画时费了不少心思, 这里分享一些心得.

前言

关于动画, 我们一般使用UIKit提供的动画来实现.

UIView动画可以设置的动画属性有:

  • 大小变化(frame)
  • 拉伸变化(bounds)
  • 中心位置(center)
  • 矩阵(transform)
  • 透明度(alpha)
  • 背景颜色(backgroundColor)
  • 拉伸内容(contentStretch)

这里主要介绍transform这个属性.

CGAffineTransform transform的类型是CGAffineTransform , 这是一个2D矩阵.

矩阵的基本知识

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

为了把二维图形的变化统一在一个坐标系里,引入了齐次坐标的概念,即把一个图形用一个三维矩阵表示,其中第三列总是(0,0,1),用来作为坐标系的标准。所以所有的变化都由前两列完成。 以上参数在矩阵中的表示为:

[ 1 ]

运算原理:原坐标设为(X,Y,1);

[ 2 ]

通过矩阵运算后的坐标[aX + cY + tx bX + dY + ty 1],我们对比一下可知: 第一种: 设a=d=1, b=c=0. [aX + cY + tx bX + dY + ty 1] = [X + tx Y + ty 1]; 可见,这个时候,坐标是按照向量(tx,ty)进行平移, 其实这也就是函数的计算原理。

CGAffineTransform CGAffineMakeTranslation(CGFloat tx,CGFloat ty)

第二种

设b=c=tx=ty=0. [aX + cY + tx bX + dY + ty 1] = [aX dY 1]; 可见,这个时候,坐标X按照a进行缩放,Y按照d进行缩放,a,d就是X,Y的比例系数,其实这也就是函数

CGAffineTransform CGAffineTransformMakeScale(CGFloat sx, CGFloat sy)

的计算原理。a对应于sx,d对应于sy。

第三种:设tx=ty=0,a=cosɵ,b=sinɵ,c=-sinɵ,d=cosɵ。 [aX + cY + tx bX + dY + ty 1] = [Xcosɵ - Ysinɵ Xsinɵ + Ycosɵ 1] ; 可见,这个时候,ɵ就是旋转的角度,逆时针为正,顺时针为负。其实这也就是函数

CGAffineTransform CGAffineTransformMakeRotation(CGFloat angle)

的计算原理。angle即ɵ的弧度表示。

总体来说, 记住下面这个结论就好.

对于CGAffineTransformMake(a,b,c,d,tx,ty) ad缩放bc旋转tx,ty位移

应用

如何做一个 指定锚点的缩放动画.

分析: 缩放动画 只需要改变b , d 的值即可. 但是此时控件的锚点是在中心点. 把当前中心点移动到你想要的点即可 , 例如, 把锚点放在相对控件原点(0,0)

//设置开始状态
CGFloat offsetX = 0 - view.size.width/2;
CGFloat offsetY = 0 - view.size.height/2;
//0.1 , 0.1 缩放到原来大小的0.1倍, 把原点放到(0,0)
view.transform = CGAffineTransformMake(0.1, 0, 0, 0.01, offsetX, offsetY);
[UIView animateWithDuration:0.5 delay:0.7 
options:UIViewAnimationOptionCurveLinear 
animations:^{
   //放大到1倍, 位移到原点
     view.transform = CGAffineTransformMake(1, 0, 0, 1, 0, 0);
        } completion:^(BOOL finished){}];

可以看到. 只使用一次变换就完成了一次位移和缩放的动画.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大壮

iOS transform(基础)

1276
来自专栏图形学与OpenGL

6.5编程实例-立方体透视投影

GLint winWidth = 600, winHeight = 600; //设置初始化窗口大小

581
来自专栏kalifaの日々

MATLAB学习笔记

who whos format long format short format bank format rat pi i exp() log() log10(...

2553
来自专栏Pulsar-V

卡尔曼滤波器(一)

设每一次采样的观测值为Px,Py,Pz 所有采样值均默认服从正态分布和马尔可夫性(可能性均可按照发生概率运算) 假设采样频率是10次/秒 根据卡尔曼滤波算法...

2603
来自专栏iOSer成长记录

iOS-圆角、边框、阴影

1265
来自专栏图形学与OpenGL

计算机图形学(OpenGL版)书中其它代码

802
来自专栏算法修养

HOJ 2317 Pimp My Ride(状态压缩DP)

Pimp My Ride My Tags (Edit) Source : TUD 2005 Time limit : 3 sec Me...

3107
来自专栏数据结构与算法

洛谷P2925 [USACO08DEC]干草出售Hay For Sale

题目描述 Farmer John suffered a terrible loss when giant Australian cockroaches ate ...

2714
来自专栏C/C++基础

矩阵转置与矩阵相乘

写这篇博客的原因是为了记录一下矩阵转置与矩阵相乘的实现代码,供日后不时之需。直接原因是今晚(2016.09.13)参加了百度2017校招的笔试(C++岗),里面...

712
来自专栏数据结构与算法

MatrixTree速成

前言 MatrixTree定理是用来解决生成树计数问题的有利工具 比如说这道题 MatrixTree定理的算法流程也非常简单 我们记矩阵A为无向图的度数矩阵 ...

3107

扫码关注云+社区