首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >更改CALayer的anchorPoint会移动视图

更改CALayer的anchorPoint会移动视图
EN

Stack Overflow用户
提问于 2009-12-28 12:49:05
回答 11查看 71.3K关注 0票数 134

我想改变anchorPoint,但保持视图不变。我尝试过NSLog、-ing、self.layer.positionself.center,不管anchorPoint有什么变化,它们都保持不变。然而,我的观点却在移动!

关于如何做到这一点,有什么建议吗?

代码语言:javascript
复制
self.layer.anchorPoint = CGPointMake(0.5, 0.5);
NSLog(@"center point: %f %f", self.layer.position.x, self.layer.position.y);
self.layer.anchorPoint = CGPointMake(1, 1);
NSLog(@"center point: %f %f", self.layer.position.x, self.layer.position.y);

输出为:

代码语言:javascript
复制
2009-12-27 20:43:24.161 Type[11289:207] center point: 272.500000 242.500000
2009-12-27 20:43:24.162 Type[11289:207] center point: 272.500000 242.500000
EN

回答 11

Stack Overflow用户

回答已采纳

发布于 2009-12-29 05:44:03

核心动画编程指南的Layer Geometry and Transforms部分解释了CALayer的位置和anchorPoint属性之间的关系。基本上,层的位置是根据层的anchorPoint的位置指定的。默认情况下,层的anchorPoint为(0.5,0.5),它位于层的中心。设置层的位置时,将设置层在其上层的坐标系中的中心位置。

因为该位置是相对于图层的anchorPoint的,所以在保持相同位置的同时更改该anchorPoint会移动图层。为了防止这种移动,您需要调整图层的位置以适应新的anchorPoint。我这样做的一种方法是抓取层的边界,将边界的宽度和高度乘以新旧锚点的归一化值,取两个anchorPoints的差值,并将该差值应用于层的位置。

您甚至可以通过将CGPointApplyAffineTransform()与您的‘s视图的CGAffineTransform一起使用来说明旋转。

票数 142
EN

Stack Overflow用户

发布于 2011-04-15 00:28:25

我也有同样的问题。Brad Larson的解决方案即使在视图旋转时也能很好地工作。以下是他的解决方案转换为代码。

代码语言:javascript
复制
-(void)setAnchorPoint:(CGPoint)anchorPoint forView:(UIView *)view
{
    CGPoint newPoint = CGPointMake(view.bounds.size.width * anchorPoint.x, 
                                   view.bounds.size.height * anchorPoint.y);
    CGPoint oldPoint = CGPointMake(view.bounds.size.width * view.layer.anchorPoint.x, 
                                   view.bounds.size.height * view.layer.anchorPoint.y);

    newPoint = CGPointApplyAffineTransform(newPoint, view.transform);
    oldPoint = CGPointApplyAffineTransform(oldPoint, view.transform);

    CGPoint position = view.layer.position;

    position.x -= oldPoint.x;
    position.x += newPoint.x;

    position.y -= oldPoint.y;
    position.y += newPoint.y;

    view.layer.position = position;
    view.layer.anchorPoint = anchorPoint;
}

和迅捷的等价物:

代码语言:javascript
复制
func setAnchorPoint(anchorPoint: CGPoint, forView view: UIView) {
    var newPoint = CGPointMake(view.bounds.size.width * anchorPoint.x, view.bounds.size.height * anchorPoint.y)
    var oldPoint = CGPointMake(view.bounds.size.width * view.layer.anchorPoint.x, view.bounds.size.height * view.layer.anchorPoint.y)

    newPoint = CGPointApplyAffineTransform(newPoint, view.transform)
    oldPoint = CGPointApplyAffineTransform(oldPoint, view.transform)

    var position = view.layer.position
    position.x -= oldPoint.x
    position.x += newPoint.x

    position.y -= oldPoint.y
    position.y += newPoint.y

    view.layer.position = position
    view.layer.anchorPoint = anchorPoint
}

SWIFT 4.x

代码语言:javascript
复制
func setAnchorPoint(anchorPoint: CGPoint, forView view: UIView) {
    var newPoint = CGPoint(x: view.bounds.size.width * anchorPoint.x,
                           y: view.bounds.size.height * anchorPoint.y)


    var oldPoint = CGPoint(x: view.bounds.size.width * view.layer.anchorPoint.x,
                           y: view.bounds.size.height * view.layer.anchorPoint.y)

    newPoint = newPoint.applying(view.transform)
    oldPoint = oldPoint.applying(view.transform)

    var position = view.layer.position
    position.x -= oldPoint.x
    position.x += newPoint.x

    position.y -= oldPoint.y
    position.y += newPoint.y

    view.layer.position = position
    view.layer.anchorPoint = anchorPoint
}
票数 208
EN

Stack Overflow用户

发布于 2009-12-28 15:41:46

解决这个问题的关键是使用frame属性,奇怪的是,它是唯一改变的东西。

Swift 2

代码语言:javascript
复制
let oldFrame = self.frame
self.layer.anchorPoint = CGPointMake(1, 1)
self.frame = oldFrame

Swift 3

代码语言:javascript
复制
let oldFrame = self.frame
self.layer.anchorPoint = CGPoint(x: 1, y: 1)
self.frame = oldFrame

然后我调整大小,它从anchorPoint缩放。然后我必须恢复旧的anchorPoint;

Swift 2

代码语言:javascript
复制
let oldFrame = self.frame
self.layer.anchorPoint = CGPointMake(0.5,0.5)
self.frame = oldFrame

Swift 3

代码语言:javascript
复制
let oldFrame = self.frame
self.layer.anchorPoint = CGPoint(x: 0.5, y: 0.5)
self.frame = oldFrame

编辑:如果旋转视图,则此选项会消失,因为如果应用了CGAffineTransform,则frame属性是未定义的。

票数 47
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1968017

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档