CoreAnimation之锚点(anchorPoint)

解释锚点最好的例子就是钟表:

1.gif

三个重叠View ,通过改变anchorPoint 改变他们的旋转中心,说白了锚点就是旋转的句柄,把手。


    self.containView =[[UIView alloc]init];
    self.containView.frame = CGRectMake(200 , 200, 5, 200);
    self.containView.backgroundColor =[UIColor redColor];
    [self.view addSubview:self.containView];
    
    
    self.containViewOne =[[UIView alloc]init];
    self.containViewOne.frame = CGRectMake(200 , 200, 5, 200);
    self.containViewOne.backgroundColor =[UIColor blueColor];
    [self.view addSubview:self.containViewOne];

    
    self.containViewTwo =[[UIView alloc]init];
    self.containViewTwo.frame = CGRectMake(200 , 200, 5, 200);
    self.containViewTwo.backgroundColor =[UIColor greenColor];
    [self.view addSubview:self.containViewTwo];

    self.containView.layer.anchorPoint = CGPointMake(0.5f, 0.95f);
    self.containViewOne.layer.anchorPoint = CGPointMake(0.5f, 0.95f);
    self.containViewTwo.layer.anchorPoint = CGPointMake(0.5f, 0.95f);

    
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(tick) userInfo:nil repeats:YES];
        //set initial hand positions
    [self tick];

- (void)tick
{
    //convert time to hours, minutes and seconds
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSUInteger units = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
    NSDateComponents *components = [calendar components:units fromDate:[NSDate date]];
    CGFloat hoursAngle = (components.hour / 12.0) * M_PI * 2.0;
    //calculate hour hand angle //calculate minute hand angle
    CGFloat minsAngle = (components.minute / 60.0) * M_PI * 2.0;
    //calculate second hand angle
    CGFloat secsAngle = (components.second / 60.0) * M_PI * 2.0;
    //rotate hands
    self.containView.transform = CGAffineTransformMakeRotation(hoursAngle);
    self.containViewOne.transform = CGAffineTransformMakeRotation(minsAngle);
    self.containViewTwo.transform = CGAffineTransformMakeRotation(secsAngle);
    self.containView.layer.shouldRasterize = YES;
    self.containViewOne.layer.shouldRasterize = YES;
    self.containViewTwo.layer.shouldRasterize = YES;
}

postion

确切地说,position是layer中的anchorPoint点在superLayer中的位置坐标。因此可以说,position点是相对suerLayer的,anchorPoint点是相对layer的,两者是相对不同的坐标空间的一个重合点。
再来看看position的原始定义: The layer’sposition in its superlayer’s coordinate space。 中文可以理解成为position是layer相对superLayer坐标空间的位置,很显然,这里的位置是根据anchorPoint来确定的.

**anchorPoint、position、frame
**

anchorPoint的默认值为(0.5,0.5),也就是anchorPoint默认在layer的中心点。默认情况下,使用addSublayer函数添加layer时,如果已知layer的frame值,根据上面的结论,那么position的值便可以用下面的公式计算:
position.x = frame.origin.x + 0.5 * bounds.size.width;
position.y = frame.origin.y + 0.5 * bounds.size.height;

里面的0.5是因为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呢?

 self.containView =[[UIView alloc]init];
    self.containView.frame = CGRectMake(200 , 200,100, 200);
    self.containView.backgroundColor =[UIColor redColor];
    [self.view addSubview:self.containView];
    NSLog(@"%@",NSStringFromCGPoint(self.containView.layer.anchorPoint));
    
    self.containView.layer.position = CGPointMake(50, 50);
     NSLog(@"%@",NSStringFromCGPoint(self.containView.layer.anchorPoint));
03.png

根据代码测试,两者互不影响,受影响的只会是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。

因为 position点和anchorPoint点是独立的,自己不会因为另外一个的改变而发生变化
参考文章 (http://blog.sina.com.cn/s/blog_155083d9e0102wi0r.html)
这篇文章描述锚点描述的很清楚(http://www.jianshu.com/p/7703e6fc6191)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容