frame、bounds表示大小和位置的属性以及center、position、anchorPosition
在iOS开发开发过程中经常会用到界面元素的frame、bounds表示大小和位置的属性以及center、position、anchorPosition等单纯表示位置的属性。这些属性究竟什么含义?彼此间又什么关系呢?下面就来浅谈一番。
首先来说说frame和bounds。
frame:描述当前界面元素在其父界面元素中的位置和大小。
bounds:描述当前界面元素在其自身坐标系统中的位置和大小。
iOS以左上角为坐标原点(0,0),以原点向右侧为X轴正方向,原点下侧为Y轴正方向。iOS采用CGPoint来表示点在坐标系上X、Y位置。同时,iOS采用CGSize来表示界面元素的宽度和高度,即视图的大小。而CGRect则是结合了CGPoint和CGSize,用来表示矩形的位置和大小。它的origin表示矩形右上角所在位置(CGPoint),size表示矩形的大小(CGSize)。
frame所描述的大小跟bounds所描述的大小是一致的,都是指界面元素的宽和高。但它们所描述的位置却不相同,frame描述的位置是指该界面元素左上角在父界面元素坐标系中的位置,而bounds描述的位置是指该界面元素左上角在自身坐标系中的位置,所以bounds描述的位置始终为(0,0)。可以说frame和bounds最大区别在于它们选取的坐标系不同。如下图:
下面再来说说center、position和anchorPosition三个单纯表示位置的属性。
说这三个属性前得先了解下CALayer。
UIView是iOS系统中界面元素的基础,所有的界面元素都是继承自它。它本身完全是由CoreAnimation来实现的。它真正的绘图部分,是由一个CALayer类来管理。UIView本身更像是一个CALayer的管理器,访问它的跟绘图和跟坐标有关的属性,例如frame,bounds等,实际上内部都是在访问它所包含的CALayer的相关属性。
center:描述当前界面元素的中心点在其父界面元素中的位置。center只能通过界面元素本身访问,而CALayer没有提供外部访问的该属性,但通过前面的描述可以知道,访问界面元素的center属性肯定也是调用了CALayer的相关属性计算得出的。一般我们可以通过下面的计算得出center。
- center.x = frame.origin.x + frame.size.width * 0.5;
- center.y = frame.origin.y + frame.size.height * 0.5;
不过通常我们用不到这样的计算。
接下来重点说说其它两个描述位置的属性position和anchorPosition。
- @property CGPoint position
- @property CGPoint anchorPoint
通过声明我们可以发现它们都是CGPoint类型。此刻我们把CALayer看作是一张打印纸被一根图钉钉在桌面上(相当于父界面元素的CALayer),可以想像这张打印纸可以绕着这根图钉旋转。那么图钉相对于打印纸的位置就可以用anchorPosition来描述,而这根图钉在桌面上的位置便是position。
在iOS中,anchorPoint点的值是用一种相对bounds的比例值来确定的,在打印纸的左上角、右下角,anchorPoint分别为(0,0), (1, 1),也就是说anchorPoint是在单元坐标空间(同时也是左手坐标系)中定义的。类似地,可以得出在打印纸纸的中心点、左下角和右上角的anchorPoint为(0.5,0.5), (0,1), (1,0)。请参考下图,注意图中分iOS与MacOS,因为两者的坐标系不相同,iOS使用左手坐标系,坐标原点在左上角,MacOS使用右手坐标系,原点在左下角,我们看iOS部分即可。
再来看看position的原始定义: The layer’s position in its superlayer’s coordinate space。中文可以理解成为position是layer相对superLayer坐标空间的位置,很显然,这里的位置是根据anchorPoint来确定的。 至于如何确定,请看下面的公式。
- position.x = frame.origin.x + anchorPoint.x * bounds.size.width;
- position.y = frame.origin.y + anchorPoint.y * bounds.size.height;
如果单方面修改layer的position位置,会对anchorPoint有什么影响呢?修改anchorPoint又如何影响position呢?
虽然说Position是根据anchorPosition来确定的,但根据代码测试,两者互不影响,受影响的只会是frame.origin,也就是layer坐标原点相对superLayer会有所改变。换句话说,frame.origin由position和anchorPoint共同决定,上面的公式可以变换成下面这样的。
- frame.origin.x = position.x - anchorPoint.x * bounds.size.width;
- frame.origin.y = position.y - anchorPoint.y * bounds.size.height;
这就解释了为什么修改anchorPoint会移动layer,因为position不受影响,只能是frame.origin做相应的改变,因而会移动layer。
Apple doc中还有一句描述是这样的:
When you specify the frame of a layer, position is set relative to the anchor point. When you specify the position of the layer, bounds is set relative to the anchor point.
当你设置图层的frame属性的时候,position点的位置(也就是position坐标)根据锚点(anchorPoint)的值来确定,而当你设置图层的position属性的时候,bounds的位置(也就是frame的orgin坐标)会根据锚点(anchorPoint)来确定。
如果我们需要修改anchorPoint,但又不想要移动layer也就是不想修改frame.origin,那么根据前面的公式,就需要position做相应地修改。简单地推导,可以得到下面的公式。
- positionNew.x = positionOld.x + (anchorPointNew.x - anchorPointOld.x) * bounds.size.width
- positionNew.y = positionOld.y + (anchorPointNew.y - anchorPointOld.y) * bounds.size.height
其实没必要这么麻烦。修改anchorPoint而不想移动layer,在修改anchorPoint后再重新设置一遍frame就可以达到目的,这时position就会自动进行相应的改变。写成函数如下。
- - (void)setAnchorPoint:(CGPoint)anchorpoint forView:(UIView *)view{
- CGRect oldFrame = view.frame;
- view.layer.anchorPoint = anchorpoint;
- view.frame = oldFrame;
- }
以上内容是本人结合开发经验并参考了部分资料而撰写的,如有不妥之处还请不吝赐教,愿大家能够互相学习,共同进步。
转载自:http://46aae4d1e2371e4aa769798941cef698.devproxy.yunshipei.com/e20914053/article/details/49950307
转载于:https://www.cnblogs.com/Jenaral/p/5443857.html
frame、bounds表示大小和位置的属性以及center、position、anchorPosition相关推荐
- html的区域大小,JavaScript位置与大小(1)之正确理解和运用与尺寸大小相关的DOM属性...
在web开发中,不可避免遇到要计算元素大小以及位置的问题,解决这类问题的方法是利用DOM提供的一些API结合兼容性处理来,所有内容大概分3篇左右的文章的来说明.本文作为第一篇,介绍DOM提供的与尺寸大 ...
- Web API-DOM-滚动事件、加载事件和元素大小和位置
滚动事件 滚动触发元素:元素.addEventListener("scroll", function () { }); 加载事件 加载元素:window.addEventListe ...
- C#根据屏幕尺寸大小重新定位控件大小和位置
float floScreenProportion = (float)Screen.PrimaryScreen.Bounds.Width / (float)240.0; CPublicParamete ...
- CSS调整图片大小和位置
调整图片大小 CSS 的width属性和 height属性可以控制元素的宽度和高度. 图片的width宽度单位类似于字体的px(像素)值. 调整图片位置 注意: <body>是块级元素,意 ...
- js 获取元素位置和大小_js 位置_Js宽度高度(详解)
一.js 获取元素的位置和大小----只读属性 1.元素的大小和位置 1.可视大小和位置 clientLeft,clientTop,clientWidth,clientHeight clientLef ...
- offsetParent、getBoundingClientRect与其他位置相关属性
offsetParent.getBoundingClientRect与其他位置相关属性 写在前面:本文章中的代码演示,默认清除的了 body 和 html 的 margin.padding. 定位父级 ...
- 判断手机是否弹出键盘,改变了手机页面高度,对应inputStatus的状态改变相关控件的大小和位置
inputResizeBodyHeight() {// 判断手机是否弹出键盘,改变了手机页面高度,对应inputStatus的状态改变相关控件的大小和位置var oldHeight =document ...
- 新型智能头盔可快速评估患者中风的大小、位置和类型
来源:IEEE电气电子工程师 The proposed helmet uses electromagnetic waves to estimate the size and position of ...
- 新技能get!判断盒子的实际大小及位置。。。
最近由于新学css,实践经验又太少了,对盒子模型的内外边距实在很难有形象的想象和理解,纠结了很久... 今天发现了一个好办法辅助布局时看到盒子的实际大小和位置,在此记录: 如例图(妙味课堂的例子): ...
最新文章
- C#在客户端和服务端操作Excel文件
- python在linux报错xe6,python出现SyntaxError: Non-ASCII character '\xe6' in file \的错误
- 面对 MySQL 查询索引失效,程序员的六大优化技巧!
- 全面分析男性护肤三大误区 - 生活至上,美容至尚!
- lightoj1234 打表技巧:分块打表
- Vue项目中使用浏览器同步测试工具 browersync
- 从0开始python后端开发_前端(html)向后端(python)传递数据_GET_POST
- 如果计算机正执行屏幕保护程序 当用户,计算机一级考试参考试题(含答案)篇篇一.doc...
- 拉格朗日法建立动力学方程
- 计算机网络复习(第六版)
- 为什么Dell官方声卡驱动安装不上的原因分析与解决?
- essay--网络常用省略语大全(ZT)
- 解决linux:docker-compose: Permission denied
- 图解通信原理与案例分析-2:如何用电信号来表示和传输0和1,远远比我们想象的要复杂得多
- ORACLE 考试的流程
- 用js写卡牌游戏(五)
- 1.HTML5文件的基本结构
- 一次线上服务CPU100%的排查过程
- 【yoyo】类,对象,方法,属性,事件的定义
- java是什么软件?如何理解Java?
热门文章
- 2019华北五省计算机应用大赛官网,“远洋航空杯”2019年华北五省(市、自治区) 及港澳台大学生计算机应用大赛举行...
- Xcode C++ and Objective-C refactoring
- iOS 用自签名证书实现 HTTPS 请求的原理
- 【Scheme归纳】4 高阶函数
- Python操作Mysql实例代码教程(查询手册)
- 分享:流言终结者——C语言内存管理
- GHOST镜像导入VHD的虚拟机
- LoadRunner参数化---数据文件属性 之 数据分配方法和数据更新方法
- 数据库连接池和线程池比较
- php网页登录制作,thinkphp5 系统登录的实现