iOS核心动画:旋转的锚点不正确

Posted

技术标签:

【中文标题】iOS核心动画:旋转的锚点不正确【英文标题】:iOS Core Animation: incorrect anchor point for rotation 【发布时间】:2011-11-15 21:59:30 【问题描述】:

我想在 ios 中实现一个基本的旋转动画,其中视图围绕其中心点不断旋转。

但是,由于某种原因,旋转的锚点始终是父视图的原点,而不是旋转视图的中心。 因此,即使我手动设置了锚点,视图也会围绕屏幕的左上角旋转。

这就是我正在做的事情:

// Add shape layer to view
CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init];
CGRect shapeRect = CGRectMake(0, 0, 100, 100);
UIBezierPath *roundedRect = [UIBezierPath bezierPathWithRoundedRect:shapeRect cornerRadius:5];
shapeLayer.path = roundedRect.CGPath;
shapeLayer.anchorPoint = CGPointMake(0.5, 0.5);
shapeLayer.fillColor = [[UIColor redColor] CGColor];

[self.view.layer addSublayer:shapeLayer];

// Set rotation animation
CATransform3D rotationTransform = CATransform3DMakeRotation(M_PI, 0, 0, 1);
CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
rotationAnimation.toValue = [NSValue valueWithCATransform3D:rotationTransform];
rotationAnimation.duration = 1.0f;
rotationAnimation.cumulative = YES;
rotationAnimation.repeatCount = HUGE_VALF;

[shapeLayer addAnimation:rotationAnimation forKey:@"transform"];

任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

路径没有定义层的边界。因此,您的图层具有CGRectZero 边界。您的路径从相对于边界的CGPointZero 开始。图层围绕它的中心旋转,也就是CGPointZero...

所以,我看到了几个选项:

layer.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(-50, -50,
                                                                100, 100)
                                        cornerRadius:5].CGPath;

或者:

layer.bounds = CGPathGetBoundingBox(layer.path);

【讨论】:

是的,这就是问题所在!除了设置边界之外,我需要设置图层的框架,以便正确定位(边界始终以零点为原点)。设置框架后,一切都按预期工作。 我认为设置层的position,保留bounds == CGRectZero,并在CGPointZero周围正确放置路径更符合逻辑。 我必须将 Frame 和 Bounds 都设置为路径边界框:)【参考方案2】:

我也遇到了同样的问题。即使手动将其设置为 (0.5, 0.5),缩放和旋转似乎也在使用左上角的锚点。我通过手动将图层的 frame 或 bounds 属性设置为与您的路径相同的大小,在我的代码中修复了它。

【讨论】:

【参考方案3】:

您可以只使用 UIView 方法而不是图层方法。它们默认围绕中心旋转。

[UIView beginAnimations];
self.view.transform = CGAffineTransformMakeRotation(M_PI);
[UIView commitAnimations];

【讨论】:

这对我来说不是一个真正的解决方案,因为我需要比 UIView 所能提供的更复杂的动画。【参考方案4】:

以下是在不使用锚点的情况下围绕特定点旋转的方法。我不确定 anchorPoint 应该为旋转动画做什么,但它似乎没有做你想要的。

“首先”平移,因此您的旋转中心位于原点。因此,向左和向上应用翻译。

然后旋转。

然后平移回所需位置。因此,上下应用翻译。

您可以通过连接矩阵同时执行这些操作。他们以相反的顺序进行。从左到右:右/下平移、旋转、左/上平移。

【讨论】:

以上是关于iOS核心动画:旋转的锚点不正确的主要内容,如果未能解决你的问题,请参考以下文章

iOS动画(三):核心动画中缩放和旋转(Swift)

iOS开发-核心动画随笔

核心动画

iOS 核心动画 - 折叠图层

iOS学习笔记09-核心动画CoreAnimation

转场/视图转换后 iOS 核心动画失败