博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS CALayer anchorPoint 的应用场景
阅读量:7055 次
发布时间:2019-06-28

本文共 5882 字,大约阅读时间需要 19 分钟。

背景

最近在看《ios核心动画高级技巧》,这本书的中文版本可以在 这里找到,看到图形几何学这一章,其中讲到的 CALayeranchorPoint 属性,发现不是很了解,所以自己发了点时间做了些研究,做了点简单的总结,主要涉及到以下主题:

  • anchorPoint 是什么
  • anchorPoint 应用场景

本文的Demo

anchorPoint 是什么

图层的anchorPoint通过position来控制它的frame的位置,你可以认为anchorPoint是用来移动图层的把柄。

上面是《ios核心动画高级技巧》书中对 anchorPoint 的解释,只看概念可能会不好理解,下面用两个例子来解释anchorPoint的概念。

例一:修改了anchorPoint 对图层的影响

如图所示,创建一个Frame为(100, 200, 100, 100)的蓝色layer,橙色的layer是修改了anchorPoint为CGPointMake(1, 1)之后的结果

修改anchorPoint对图层的影响1

1、分析蓝色layer

默认的anchorPoint是(0.5, 0.5),位于layer的中间,position也是位于layer的中间,layer以中心点为定位点,此时positon的意义是 layer的中心点距离父layer的原点的位置是position.x,position.y ,所以最终的frame位置如图所示为 {
{100, 100}, {100, 100}}

2、分析橙色layer anchorPoint是(1, 1),位于layer的右下角,position也是位于layer的右下角,layer以右下角为定位点,此时positon的意义是 layer的右下角距离父layer的原点的位置是position.x,position.y ,所以最终的frame位置如图所示为 {

{50, 50}, {100, 100}}

3、两个重要的结论

  1. anchorPoint和position是一一对应的,anchorPoint是相对于layer自身的,是一个单位坐标 (0~1, 0~1) ,表示当前layer的定位点是位于layer的什么位置,定位点决定了layer相对于父layer的关系以及layer的旋转中心,后面会有旋转的例子
  2. 只修改了anchorPoint不会使position变化,但是图层位置会变化,因为定位点的位置改变了,导致最终Layer的Frame改变了,Frame是最终决定Layer位置的。

例子的代码如下:

// anchorPoint 对图层的影响    layer = [[CALayer alloc] init];    layer.frame = CGRectMake(100, 200, 100, 100);    layer.borderColor = [UIColor blueColor].CGColor;    layer.borderWidth = 1;    layer.anchorPoint = CGPointMake(0.5, 0.5);    [self.view.layer addSublayer:layer];    NSLog(@"layer position = %@, anchorPoint = %@  frame = %@", NSStringFromCGPoint(layer.position), NSStringFromCGPoint(layer.anchorPoint), NSStringFromCGRect(layer.frame));    {        CALayer* copyLayer = [self cloneLayer:layer];        copyLayer.borderColor = [UIColor orangeColor].CGColor;        [self.view.layer addSublayer:copyLayer];        // 默认的anchorPoint位置为(0.5, 0.5),和position是对应的        // 需要移动anchorPoint到layer的右下角,        // 假设认为anchorPoint的位置是固定的,怎样才能把anchorPoint定位到位置为(1, 1)        // 需要把整个的layer往上和往左移动(layer.width * 0.5)个点才能够做到        // 这样会导致frame的origin的变化,也就是layer会往左上角偏移了        // position的值没有改变,anchorPoint位置是对应的,下面会进行谈论        copyLayer.anchorPoint = CGPointMake(1, 1);        NSLog(@"layer position = %@, anchorPoint = %@  frame = %@", NSStringFromCGPoint(copyLayer.position), NSStringFromCGPoint(copyLayer.anchorPoint), NSStringFromCGRect(copyLayer.frame));                // 回到这里,继续讨论anchorPoint引起的frame的变化而position不变        // anchorPoint是layer定位点(包括旋转和缩放,是相对于layer自身的,是一个单位坐标的点)        // position是和anchorPoint对应的点,是layer相对于父layer的定位点,        // anchorPoint=(0.5, 0.5),layer的中心位置相对于父layer原点的位置为position        // 因为在只修改anchorPoint的情况下不改变position的值,所以:        // anchorPoint=(1, 1),layer的右下角位置相对于父layer原点的位置为position    }复制代码

例二:Frame不变,修改了anchorPoint 对图层的影响

如图所示,创建一个Frame为(100, 300, 100, 100)的蓝色layer,橙色的layer是修改了anchorPoint为CGPointMake(0, 0)之后但是Frame不变的结果,红色的layer是修改了anchorPoint为CGPointMake(1, 1)之后但是Frame不变的结果

Frame不变,修改了anchorPoint 对图层的影响

1、分析橙色Layer

在保持Frame不变的情况下,anchorPoint是(0, 0),位于layer的左上角,position也是位于layer的左上角,layer以左上角为定位点,此时positon的意义是 layer的左上角距离父layer的原点的位置是position.x,position.y ,对layer进行45°的旋转之后,如图Layer以左上角做了顺时针的45°旋转。

2、分析红色Layer

在保持Frame不变的情况下,anchorPoint是(1, 01),位于layer的右下角,position也是位于layer的右下角,layer以右下角为定位点,此时positon的意义是 layer的右下距离父layer的原点的位置是position.x,position.y ,对layer进行45°的旋转之后,如图Layer以右下角做了顺时针的45°旋转。

例子的代码如下:

// 在Frame不变的情况下讨论anchorPoint对position的影响    // 可以这么认为,position是因变量,anchorPoint是自变量    // anchorPoint和position是一一对应的,是同一个点    layer = [[CALayer alloc] init];    layer.borderColor = [UIColor blueColor].CGColor;    layer.borderWidth = 1;    layer.anchorPoint = CGPointMake(1, 1);    layer.frame = CGRectMake(100, 300, 100, 100);    [self.view.layer addSublayer:layer];        {        CALayer* copylayer = [self cloneLayer:layer];        copylayer.borderColor = [UIColor orangeColor].CGColor;        [self.view.layer addSublayer:copylayer];                // Frame不变,anchorPoint设置到右下角,positon位置也会变到右下角{150, 500}        copylayer.anchorPoint = CGPointMake(1, 1);        copylayer.frame = CGRectMake(100, 300, 100, 100);        NSLog(@"layer.position = %@", NSStringFromCGPoint(copylayer.position));                // 旋转        copylayer.affineTransform = CGAffineTransformRotate(copylayer.affineTransform, M_PI_4);    }        {        CALayer* copylayer = [self cloneLayer:layer];        copylayer.borderColor = [UIColor orangeColor].CGColor;        [self.view.layer addSublayer:copylayer];                // Frame不变,anchorPoint设置到坐上角,positon位置也会变到坐上角{50, 400}        copylayer.anchorPoint = CGPointMake(0, 0);        copylayer.frame = CGRectMake(100, 300, 100, 100);        NSLog(@"layer.position = %@", NSStringFromCGPoint(copylayer.position));                // 旋转        copylayer.affineTransform = CGAffineTransformRotate(copylayer.affineTransform, M_PI_4);    }复制代码

anchorPoint 应用场景

例子来自于《ios核心动画高级技巧》书中国的

例子可以在我的git上找到

初始的时钟指针在表盘中的位置如下:

初始的时钟指针在表盘中的位置

// 秒针layer frame:{
{
124, 77}, {
8, 102}} anchorPoint:{
0.5, 0.5} position:{
128, 128}// 分针layer frame:{
{
118, 75}, {
20, 106}} anchorPoint:{
0.5, 0.5} position:{
128, 128}// 时针 layer frame:{
{
113, 81}, {
30, 94}} anchorPoint:{
0.5, 0.5} position:{
128, 128}复制代码

没有设置anchorPoint的指针走动效果:

没有设置anchorPoint的指针走动效果
根据以上的分析我们知道原因是默认的anchorPoint为{0.5, 0.5},也就是旋转中心是指针的中心点导致的效果如此,知道原因了修改也不难了,最简单的做法就是把anchorPoint设置为{0.5, 0.9}即可。

//adjust anchor points    self.secondHand.layer.anchorPoint = CGPointMake(0.5f, 0.9f);    self.minuteHand.layer.anchorPoint = CGPointMake(0.5f, 0.9f);    self.hourHand.layer.anchorPoint = CGPointMake(0.5f, 0.9f);复制代码

对应的指针的layer变化:

// 秒针layer frame:{
{124, 36.2}, {8, 102}} anchorPoint:{0.5, 0.89} position:{128, 128}// 分针layer frame:{
{118, 32.6}, {20, 106}} anchorPoint:{0.5, 0.8} position:{128, 128}// 时针layer frame:{
{113, 43.4}, {30, 94}} anchorPoint:{0.5, 0.89} position:{128, 128}复制代码

效果如下:

设置anchorPoint的指针走动效果

总结

以上是Layer中anchorPoint属性的一些总结以及一个应用场景,如有不妥之处敬请指教。

转载于:https://juejin.im/post/5ca5d484f265da3077190db4

你可能感兴趣的文章
使用postMessage实现跨窗口消息传递
查看>>
VIM跳转和小改动
查看>>
svn 常用指令 及 常见问题记录
查看>>
修改全志A10, A20的Nand分区大小
查看>>
python class和class(object)用法区别
查看>>
ejs标签
查看>>
我的友情链接
查看>>
Linux/Unix批量处理产生
查看>>
XFS和RAID6性能优化
查看>>
corosync+pacemaker 实现高可用集群(三)
查看>>
linux下的java开发环境
查看>>
Bootstrap使用记录
查看>>
从一场场大型网站灾难过后的BUG:根
查看>>
Linux系统下怎样利用nc命令来监控检测服务器的端口使用情况
查看>>
git命令总结
查看>>
tomcat高访问jvm配置
查看>>
谢烟客---------二进制安装MariaDB,管理关系型数据库的基本组件
查看>>
JS 判断手机浏览器
查看>>
Xcode WorkSpace静态库多项目依赖
查看>>
【C语言】 实现memset
查看>>