旋转CALayer 90度?

33

如何将CALayer旋转90度?我需要旋转包括子层和坐标系在内的所有内容。


如果需要,请不要忘记设置图层的锚点。如果您将其放在中间而不是顶部,则它的翻转方式将不同。 - mrcendre
5个回答

60

Obj-C:

theLayer.transform = CATransform3DMakeRotation(90.0 / 180.0 * M_PI, 0.0, 0.0, 1.0);

Swift:

->

Swift:

theLayer.transform = CATransform3DMakeRotation(90.0 / 180.0 * .pi, 0.0, 0.0, 1.0)

也就是说,将该层进行旋转使其绕z轴旋转90度(π / 2弧度),并且该旋转的100%发生在z轴周围。


1
M_PI 是 Double 类型,而 CATransform3DMakeRotation 要求角度为 CGFloat 类型,因此应使用 CGFloat(M_PI)。 - Mina Kolta
在C语言中,从double类型转换为CGFloat类型是隐式的(而且在C和Objective-C中进行强制类型转换的形式为*(T)expression,而不是T(expression)*。你是想到Swift或C++了吗?)此外,在上面的语句中,M_PI被乘以一个double类型,因此它被扩展了,这就破坏了类型转换的目的。 - Jonathan Grynspan
如何以中心点为锚点使其旋转?它的旋转会影响整个图层。 - apinho
M_PI在Swift中会导致类型转换问题,已被弃用,推荐使用Type.pi.pi,这将使用正确的类型(在本例中为CGFloat.pi)。 - Abhi Beckert
@apinho 将.anchor设置为帧的中心 - Fattie
确保在旋转“theLayer”之后设置其框架。 - Mason Ballowe

13

如果我需要在我的应用程序中进行动画处理,我会使用类似于以下的代码:

- (NSObject *) defineZRotation {
    // Define rotation on z axis
    float degreesVariance = 90;
    // object will always take shortest path, so that
    // a rotation of less than 180 deg will move clockwise, and more than will move counterclockwise
    float radiansToRotate = DegreesToRadians( degreesVariance );
    CATransform3D zRotation;
    zRotation = CATransform3DMakeRotation(radiansToRotate, 0, 0, 1.0);  
    // create an animation to hold "zRotation" transform
    CABasicAnimation *animateZRotation;
    animateZRotation = [CABasicAnimation animationWithKeyPath:@"transform"];
    // Assign "zRotation" to animation
    animateZRotation.toValue = [NSValue valueWithCATransform3D:zRotation];
    // Duration, repeat count, etc
    animateZRotation.duration = 1.5;//change this depending on your animation needs
    // Here set cumulative, repeatCount, kCAFillMode, and others found in
    // the CABasicAnimation Class Reference.
    return animateZRotation;
}

当然可以在任何地方使用它,如果不适合您的需求,就不必从方法中返回它。


不需要为旋转视图创建CAAnimation对象。对此,animateWithDuration:animations完全可以胜任。有关更多详细信息,请参见我的答案。 - Duncan C
@Duncan 我认为这种方法只适用于UIView,而不是CALayer。请查看我对你的回答。 - Rab

8

基本上就像这样:

CGAffineTransform rotateTransform = CGAffineTransformMakeRotation(M_PI / 2.0); [myCALayer setAffineTransform:rotateTransform];

编辑:它将根据平台(iOS或Mac OS)顺时针或逆时针旋转。


1

向右旋转90度:

myView.transform = CGAffineTransformMakeRotation(M_PI_2);

0
Rab展示了如何使用CAAnimation对象来实现。实际上,它比那更简单:
[myView animateWithDuration: 0.25   animations:  ^{     myView.transform = CGAffineTransformMakeRotation(M_PI/2);   }];

(从Chris的答案中提取变换行 - 太懒了,因为他已经提供了完美的代码。)

Chris的代码可以旋转视图而不带动画。我上面的代码将使用动画执行相同的操作。

默认情况下,动画使用缓入缓出的时间。您可以使用稍微更复杂的版本的animateWithDuration调用进行更改(使用animateWithDuration:delay:options:animations:completion:代替,并在options参数中传递所需的时间)。


animateWithDuration:animations:是UIView的基于块的方法。这里的问题是如何对CALayer进行动画处理-- CALayer没有这个方法,或者至少没有记录下来。并且在2010年,方法animateWithDuration:animations:还不存在(我认为,在Obj-C中也没有任何基于块的内容)...因此,如果应用它,这将更像是“2012年的更新”。 - Rab
Chris的代码也将使用CALayer的标准动画时长进行动画处理。 - vikingosegundo
公正的观点是基于块的动画可能在2010年不存在,而且这个问题特别询问了CALayer而不是视图动画。UIView动画在底层生成CAAnimations,但如果你要动画的层不是视图的支持层,你只能使用UIView动画。 - Duncan C
@vikingosegundo,像我的代码一样,Chris的代码改变了视图的转换,而不是图层的。我相信改变视图属性不会像改变可动画图层属性那样创建隐式动画。(这是一个旧线程,但有人刚刚对我的答案进行了负面评价,促使我重新访问它。) - Duncan C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接