关于frame

  • frame是一个复合属性,由center、bounds和transform共同计算而来。
  • transform改变,frame会受到影响,但是center和bounds不会受到影响。也就是你使用transform来缩放,bounds是不会变的。那么由center和bounds计算得到的frame是永远保持transform为identity时的状态。这也是为什么把transform设为identity后,view会回归到最初状态。

关于transform的计算

当你使用view.transform = xxx时候,它到底是怎么起作用的?首先,它是一个矩阵,使用矩阵乘法,对view的frame进行变换,得到新的变换,那么这个逻辑是怎样的?

  • 它是针对父视图坐标的。
  • 它是针对view的初始中心为坐标的:“初始”是指transform值为identity时的状态,即没有任何的缩放、平移或旋转;“中心”默认是view方块的中心,但实际是anchorPoint

那么viewA.transform = myTransform这么一段代码就等价于:

  1. 把父视图坐标系的原点移动到view的中心,计算中心坐标系的frame,得到frame1:
CGRect frame1 = CGRectMake(
-originalFrame2.size.width/2.0,
-originalFrame2.size.height/2.0,
originalFrame2.size.width,
originalFrame2.size.height);
复制代码
  1. 以坐标系改变后的frame(即centerFrame)计算,使用矩阵乘法应用transform,得到frame2:CGRect frame2 = CGRectApplyAffineTransform(frame2, myTransform)

  2. 再把结果转回原父视图坐标系,得到frame3:

CGRect frame3 = CGRectMake(
frame2.origin.x + CGRectGetMidX(originalFrame),
frame2.origin.y + CGRectGetMidY(originalFrame),
frame2.size.width,
frame2.size.height);
复制代码

这么做的好处便是在缩放的时候,是针对view当前位置的,这样view的原点不会改变,也就是缩放只会产生缩放的效果,而不会产生平移。假设使用父视图原点,frame为{10,20,100,100},缩放后变成{5,10,50,50},那么frame不仅变小了,也和原点更近了。

怎么计算两个frame之间的transform

给你一个view和一个目标frame,求一个transform,使得把这个transform给view后,view的frame等于目标frame。

在处理动画的时候会用到。

因为缩放会影响平移,而平移却不会影响缩放,所以先平移到中心和目标frame一致,然后缩放。

平移的距离就是两个center的差值,缩放比例的就是两个frame的边长之比。

即:

-(CGAffineTransform)transformFromRect:(CGRect)fromRect toRect:(CGRect)toRect{CGAffineTransform moveTrans = CGAffineTransformMakeTranslation(CGRectGetMidX(toRect) - CGRectGetMidX(fromRect), CGRectGetMidY(toRect) - CGRectGetMidY(fromRect));CGAffineTransform scaleTrans = CGAffineTransformMakeScale(toRect.size.width / fromRect.size.width, toRect.size.height / fromRect.size.height);//右边先执行return CGAffineTransformConcat(scaleTrans, moveTrans);
}
复制代码

为什么使用transform动画而不是设置frame?

如果transform里包含了旋转,那么计算出来的frame就没有意义了,因为frame总是描述一个“摆正的”方块,而旋转后的方块是没法描述的。

但对于只有平移和缩放,用上述逻辑是可以计算的。我在做一个过场动画的时候用到了这个,动画是类似系统相册那样从一个小图逐渐放大到全屏,所以你拥有的信息是一个起始的frame,以这个为开始动画。

我尝试了通过直接设置frame来执行动画,但发现效果糟糕,因为动画虽然有一个过程,但其实从动画一开始,frame就已经修改了。如果直接设置frame,那么开始的时候,子视图就会按变化后的frame来重新布局,而不是跟随父视图一起慢慢变化

动画是渲染呈现上的样子,而实际的数值却是另一种样子,在core animation里有模型树呈现树的区别。

举个例子:

测试view是灰色,它有一个子视图是红色:

-(void)layoutSubviews{innerView.frame = CGRectMake(10, 10, self.frame.size.width-20, self.frame.size.height-20);
}
复制代码

内部的view保持和父视图10的边距。所以看第一个动画,在刚开始的时候,红色的view就变成了动画结束时的大小,而第二个动画使用transform变换,其实layoutSubviews并没有调用,但是却得到了想要的效果。貌似transform只是影响了view的渲染,而且是影响了整个的子视图数,就像把这个view当做一张图片一样缩小了,而内部却不需要重新布局。

使用transform效果更好,那么就要从一个初始frame计算得到transform,使得赋值给view后,它就是到初始frame的位置。所以就有了上面的transform计算。

iOS:重识Transform和frame相关推荐

  1. 【重识 HTML + CSS】网页基础知识、基本 HTML 标签

    重识 HTML + CSS 网页的基础知识 网页的显示过程 缓存(cache)技术 浏览器内核 常用 HTML 元素 DOCTYPE 文档说明 html 元素:根元素 lang 属性 head 元素: ...

  2. 【重识云原生】计算第2.4节——主流虚拟化技术之KVM

    <重识云原生系列>专题索引: 第一章--不谋全局不足以谋一域 第二章计算第1节--计算虚拟化技术总述 第二章计算第2节--主流虚拟化技术之VMare ESXi 第二章计算第3节--主流虚拟 ...

  3. 从0开始的微服务架构:(一)重识微服务架构

    2019独角兽企业重金招聘Python工程师标准>>> 导语 虽然已经红了很久,但是"微服务架构"正变得越来越重要,也将继续火下去. 各个公司与技术人员都在分享微 ...

  4. Re:从0开始的微服务架构:(一)重识微服务架构--转

    原文地址:http://www.infoq.com/cn/articles/micro-service-architecture-from-zero?utm_source=infoq&utm_ ...

  5. clickhouse原理解析与开发实战 pdf_重识SSM,“超高频面试点+源码解析+实战PDF”,一次性干掉全拿走...

    重识SSM,"超高频面试点"+"源码解析"+"实战PDF",一次性干掉全拿走!! 01 超高频面试点知识篇 1.1 Spring超高频面试点 ...

  6. 数据结构学习笔记(五):重识字符串(String)

    目录 1 字符串与数组的关系 1.1 字符串与数组的联系 1.2 字符串与数组的区别 2 实现字符串的链式存储(Java) 3 子串查找的简单实现 1 字符串与数组的关系 1.1 字符串与数组的联系 ...

  7. 零基础教你玩转ESP8266(一) 重识ESP8266

    零基础教你玩转ESP8266(一) 重识ESP8266     单片机菜鸟 单片机菜鸟 当前离线 积分 24734 TA的每日心情 开心 2018-10-25 09:07 签到天数: 507 天 [L ...

  8. 【重识 HTML + CSS】知识点目录

    重识 HTML + CSS 前言 基本 HTML 标签 基本 CSS 属性 CSS 选择器 CSS 特性 HTML 列表.表格.表单 HTML 元素类型 盒子模型相关知识点 Photoshop 简单使 ...

  9. 【重识 HTML + CSS】项目实战

    项目实战 常见项目目录 CSS Reset CSS 编码规范 浏览器私有前缀 CSS 知识补充 CSS 属性 - white-space CSS 属性 - text-overflow image-se ...

最新文章

  1. 华为员工实力炫富,工作六年一套房一辆豪车,存款六十万
  2. linux创建mysql视图,MySQL视图入门浅析
  3. 例1:反转一个三位整数
  4. 想要配置文件生效 需要通过添加到web.xml加载到内存中
  5. 拓端tecdat|R语言弹性网络Elastic Net正则化惩罚回归模型交叉验证可视化
  6. 解析二进制文件的工具方法
  7. ppt入门到精通全套视频教程,Word+Excel+PPT三合一教程(15G)
  8. 使用ViewPage + Fragment,ViewPage所在的activity重建时的问题
  9. 图的遍历:BFS算法学习
  10. 台式计算机用什么网卡,台式电脑无线网卡怎么用 台式机无线网卡使用教程 - WiFi共享大师...
  11. 08年最感人的文章,不信你不哭
  12. JavaScript - jQuery(一)
  13. Django 配置MySQL
  14. html中计时器,计时器.html
  15. 【论文导读】MATRIX FACTORIZATION TECHNIQUES FOR RECOMMENDER SYSTEMS
  16. 使用LabVIEW 实现物体识别、图像分割、文字识别、人脸识别等深度视觉
  17. 快来智影:微电影的特征有哪些?
  18. 汇编学习实战修改win32扫雷
  19. 计算两个向量的互信息(Mutual Information) matlab程序
  20. [渝粤教育] 西南科技大学 电工学与电子学 在线考试复习资料

热门文章

  1. OpenStack常见命令与问题集合
  2. 处理Linux中大量ESTABLISHED进程
  3. Netbackup7.5 access to the client was not allowed(59)问题解决
  4. 另一个SqlParameterCollection 中已包含 SqlParameter[解决方案]
  5. Kali linux2.0里Metasploit的postgresql selected, no connection问题解决
  6. nginx 反向代理时丢失端口的解决方案(转)
  7. 解决问题 “You don‘t have permission to access /index.html on this server.”
  8. 解决nginx反向代理缓存不起作用的问题
  9. 如何在GitHub上搜索提交消息?
  10. 撤消git update-index --assume-unchanged file