彻底理解position与anchorPoint - Wonderffee's Blog(转)
引言
相信初接触到CALayer的人都会遇到以下几个问题:
为什么修改anchorPoint会移动layer的位置?
CALayer的position点是哪一点呢?
anchorPoint与position有什么关系?
我也迷惑过,找过网上的教程,大部分都是复制粘贴的,有些是翻译的文章但很有问题,看得似懂非懂,还是自己写代码彻底弄懂了,做点笔记吧。
每一个UIView内部都默认关联着一个CALayer, UIView有frame、bounds和center三个属性,CALayer也有类似的属性,分别为frame、bounds、position、anchorPoint。frame和bounds比较好理解,bounds可以视为x坐标和y坐标都为0的frame,那position、anchorPoint是什么呢?先看看两者的原型,可知都是CGPoint点。
@property CGPoint position
@property CGPoint anchorPoint
anchorPoint
一般都是先介绍position,再介绍anchorPoint。我这里反过来,先来说说anchorPoint。
从一个例子开始入手吧,想象一下,把一张A4白纸用图钉订在书桌上,如果订得不是很紧的话,白纸就可以沿顺时针或逆时针方向围绕图钉旋转,这时候图钉就起着支点的作用。我们要解释的anchorPoint就相当于白纸上的图钉,它主要的作用就是用来作为变换的支点,旋转就是一种变换,类似的还有平移、缩放。
继续扩展,很明显,白纸的旋转形态随图钉的位置不同而不同,图钉订在白纸的正中间与左上角时分别造就了两种旋转形态,这是由图钉(anchorPoint)的位置决定的。如何衡量图钉(anchorPoint)在白纸中的位置呢?在iOS中,anchorPoint点的值是用一种相对bounds的比例值来确定的,在白纸的左上角、右下角,anchorPoint分为为(0,0), (1, 1),也就是说anchorPoint是在单元坐标空间(同时也是左手坐标系)中定义的。类似地,可以得出在白纸的中心点、左下角和右上角的anchorPoint为(0.5,0.5), (0,1), (1,0)。
然后再来看下面两张图,注意图中分iOS与MacOS,因为两者的坐标系不相同,iOS使用左手坐标系,坐标原点在左上角,MacOS使用右手坐标系,原点在左下角,我们看iOS部分即可。

图1

图2
像UIView有superView与subView的概念一样,CALayer也有superLayer与layer的概念,前面说到的白纸和图中的矩形可以理解为layer,书桌和图中矩形以外的坐标系可以理解成superLayer。如果各自以左上角为原点,则在图中有相对的两个坐标空间。
position
在图1中,anchorPoint有(0.5,0.5)和(0,0)两种情况,分别为矩形的中心点与原点。那么,这两个anchorPoint在superLayer中的实际位置分别为多少呢?简单计算一下就可以得到(100, 100)和(40, 60),把这两个值分别与各自的position值比较,发现完全一致,该不会是巧合?
这时候可以大胆猜测一下,position是不是就是anchorPoint在superLayer中的位置呢?答案是确定的,更确切地说,position是layer中的anchorPoint点在superLayer中的位置坐标。因此可以说, position点是相对suerLayer的,anchorPoint点是相对layer的,两者是相对不同的坐标空间的一个重合点。
再来看看position的原始定义: The layer’s position in its superlayer’s coordinate space。
中文可以理解成为position是layer相对superLayer坐标空间的位置,很显然,这里的位置是根据anchorPoint来确定的。
图2中是矩形沿不同的anchorPoint点旋转的形态,这就是类似于刚才讲的图钉订在白纸的正中间与左上角时分别造就了两种旋转形态。
anchorPoint、position、frame
anchorPoint的默认值为(0.5,0.5),也就是anchorPoint默认在layer的中心点。默认情况下,使用addSublayer函数添加layer时,如果已知layer的frame值,根据上面的结论,那么position的值便可以用下面的公式计算:
1 |
|
里面的0.5是因为anchorPoint取默认值,更通用的公式应该是下面的:
1 |
|
下面再来看另外两个问题,如果单方面修改layer的position位置,会对anchorPoint有什么影响呢?修改anchorPoint又如何影响position呢?
根据代码测试,两者互不影响,受影响的只会是frame.origin,也就是layer坐标原点相对superLayer会有所改变。换句话说,frame.origin由position和anchorPoint共同决定,上面的公式可以变换成下面这样的:
1 |
|
这就解释了为什么修改anchorPoint会移动layer,因为position不受影响,只能是frame.origin做相应的改变,因而会移动layer。
理解与运用
在Apple doc对frame的描述中有这么一句话:
Layers have an implicit frame that is a function of the position, bounds, anchorPoint, and transform properties.
可以看到我们推导的公式基本符合这段描述,只不过还缺少了transform,加上transform的话就比较复杂,这里就不展开讲了。
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根据锚点(anchorPoint)的值来确定,而当你设置图层的position属性的时候,bounds会根据锚点(anchorPoint)来确定。
这段翻译的上半句根据前面的公式容易理解,后半句可能就有点令人迷惑了,当修改position时,bounds的width与height会随之修改吗?其实,position是点,bounds是矩形,根据锚点(anchorPoint)来确定的只是它们的位置,而不是内部属性。所以,上面这段英文这么翻译就容易理解了:
当你设置图层的frame属性的时候,position点的位置(也就是position坐标)根据锚点(anchorPoint)的值来确定,而当你设置图层的position属性的时候,bounds的位置(也就是frame的orgin坐标)会根据锚点(anchorPoint)来确定。
在实际情况中,可能还有这样一种需求,我需要修改anchorPoint,但又不想要移动layer也就是不想修改frame.origin,那么根据前面的公式,就需要position做相应地修改。简单地推导,可以得到下面的公式:
1 |
|
但是在实际使用没必要这么麻烦。修改anchorPoint而不想移动layer,在修改anchorPoint后再重新设置一遍frame就可以达到目的,这时position就会自动进行相应的改变。写成函数就是下面这样的:
1 |
|
总结
1、position是layer中的anchorPoint在superLayer中的位置坐标。
2、互不影响原则:单独修改position与anchorPoint中任何一个属性都不影响另一个属性。
3、frame、position与anchorPoint有以下关系:
1 |
|
第2条的互不影响原则还可以这样理解:position与anchorPoint是处于不同坐标空间中的重合点,修改重合点在一个坐标空间的位置不影响该重合点在另一个坐标空间中的位置。
后记
20140323:关于修改anchorPoint为什么会移动layer的位置,在刚才回复finder的评论时想到了一个更好的解释:
还是以桌子与白纸为例,如果固定图钉在桌上的位置,也就是positon不变,这个时候图钉处在白纸的不同地方就是不同的anchorPoint,相应地也就是不同的frame。
另一方面,如果固定图钉在白纸上的位置(没订在桌子上),不管怎么平移白纸,anchorPoint肯定是不变的,但frame肯定是随之变化的
彻底理解position与anchorPoint - Wonderffee's Blog(转)的更多相关文章
- 彻底理解position与anchorPoint
引言 相信初接触到CALayer的人都会遇到以下几个问题: 为什么修改anchorPoint会移动layer的位置?CALayer的position点是哪一点呢?anchorPoint与positio ...
- [Think] position与anchorPoint关系
1.简介: 最近在学习动画,所以接触到了CAlayer类. 其中的position与anchorPoint关系一感觉一头雾水,网上有篇文章 彻底理解position和anchorPoint关系 里面 ...
- iOS-CALayer中position与anchorPoint详解
iOS-CALayer中position与anchorPoint详解 属性介绍 CALayer通过四个属性来确定大小和位置, 分别为:frame.bounds.position.anchorPoint ...
- position与anchorPoint
相信初接触到CALayer的人都会遇到以下几个问题: 为什么修改anchorPoint会移动layer的位置?CALayer的position点是哪一点呢?anchorPoint与position有什 ...
- CALayer 易混淆的两个属性 - position和anchorPoint
1.简单介绍 CALayer有2个非常重要的属性:position和anchorPoint @property CGPoint position; ...
- Position和anchorPoint
Main.storyboard ViewController.m // // ViewController.m // 7A12.position和anchorPoint // // Create ...
- iOS开发——使用OC篇&frame,bounds,center,position,anchorPoint总结
frame,bounds,center,position,anchorPoint总结 图层的 position 属性是一个 CGPoint 的值,它指定图层相当于它父图层的位置, 该值基于父图层的坐标 ...
- CALayer属性:position和anchorPoint
一.position和anchorPoint 1.简单介绍 CALayer有2个非常重要的属性:position和anchorPoint @property CGPoint position; 用来设 ...
- ios开发图层layer与核心动画二:CATransform3D,CAlayear和UIView区别,layer的position和anchorpoint
一:CATransform3D #import "ViewController.h" @interface ViewController () @property (weak, n ...
随机推荐
- ASP.NET服务端基本控件介绍
ASP.NET服务端基本控件介绍 大概分为三种控件: HTML控件,ASP.NET把HTML控件当成普通字符串渲染到浏览器端,不去检查正确性,无法在服务端进行处理ASP.NET服务端控件,经过ASP. ...
- jquery 插件的编写
/** * 插件的学习 * 原文地址:http://www.cnblogs.com/Wayou/p/jquery_plugin_tutorial.html#home */ ;(function($, ...
- js判断是否全是相同的字符串
isSameStr("aa2a") //不都是相同的字符 function isSameStr(str){ var tem=0; for(var i=0;i<str.leng ...
- yii2 gii页面404和debug调试栏无法显示解决方法
在debug和gii配置项中加一项: 'allowedIPs' => ['127.0.0.1', '::1', '*.*.*.*']即可 注:因为yii默认只让127.0.0.1访问
- C++相关资源
http://www.cnblogs.com/xi52qian/p/4186983.html语言ISO/IEC JTC1/SC22/WG21 - The C++ Standards Committee ...
- windows2003网络负载平衡设置
问题 随着计算机技术的不断发展,单台计算机的性能和可靠性越来越高.但现实中还是有许多应用是单台计算机难以达到,例如: 1.银行存储用户数据的数据库服务器必须保证24小时不间断的运转,并在发生严重硬件故 ...
- 8月1日起,这些新政将影响移动互联网产业-b
今天,国家互联网信息办公室发布<移动互联网应用程序信息服务管理规定>.这项规定将从8月1日起生效,其中侧重对两类玩家提出了监管意见,他们分别是: 移动互联网应用程序提供者,即提供信息服务的 ...
- Java 判断操作系统类型(适用于各种操作系统)
Java 判断操作系统类型(适用于各种操作系统) 最近一段时间写一个授权的程序,需要获取很多信息来保证程序不能随意复制使用,必须经过授权才可以. 为了限制用户使用的操作系统,必须有统一的方法来获取才可 ...
- jQuery制作Web全屏效果
需要的资源 1.jQuery版本库是必不可少的2.jQuery FullScreen plugin如果你下载不方便的话,你可以直接把下面的代码copy到你本地JQuery FullScreen plu ...
- XMLHttpRequest2的进步之处
本文参考自:XMLHttpRequest2 新技巧 (重点保留demo,方便自己日后查阅) HTML5是现在web开发中的热点,虽然关于web app和local app一直有争论,但是从技术学习的角 ...