CALayer - CABasicAnimation不围绕中心/锚点缩放

27
使用以下代码,我一直试图让我的CALayer围绕其中心缩放 - 但它是以左上角(0,0)为中心缩放的。我看到了这个问题:CALayer中的锚点并尝试设置了anchorPoint - 但在我设置之前它已经是[.5,.5]了,并且设置没有任何区别。还尝试设置contentsGravity
设置如下:我在self.view.layer中添加了一个CAShapeLayer,在其中进行一些绘图,然后添加CABasicAnimation。动画运行良好 - 但它向顶部/左侧缩放 - 而不是视图的中心。
我已经调整了几个小时 - 这一定是什么简单的东西,但我还没有弄清楚。
shapeLayer.anchorPoint = CGPointMake(.5,.5);
shapeLayer.contentsGravity = @"center";

printf("anchorPoint %f  %f\n", shapeLayer.anchorPoint.x, shapeLayer.anchorPoint.y);

CABasicAnimation *animation =
[CABasicAnimation animationWithKeyPath:@"transform.scale"];

animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
animation.toValue =   [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)];

[animation setDuration:1.0];
animation.fillMode=kCAFillModeForwards;
animation.removedOnCompletion=NO;
[shapeLayer addAnimation:animation forKey:@"zoom"];
4个回答

56

你的图层的bounds是什么?

我打赌它的尺寸为零;试着将其大小设置为与你的形状相同。

CAShapeLayer 将形状绘制为一种覆盖层,与你在普通的CALayer中使用的contentsboundscontentsGravity等独立。这可能有点让人困惑。


1
我曾经遇到过类似的问题,可能是图层的框架没有设置好。然后锚点起了作用。 - cynistersix
我遇到了同样的问题,但是还没有解决。 如果我将边界应用于CAShape图层,则其位置会完全改变, 但是如果我不应用边界,则它会从VC的左上角开始动画:( - hmali

5

确保在视图创建后再添加动画。如果您尝试在viewDidLoad中添加动画,可能不起作用。请尝试将其添加到viewDidAppear中。

我只知道Swift,但这里有一个例子:

override func viewDidAppear (animated: Bool) {
    addPulsation(yourButton)
}

func addPulsation (button: UIButton) {
    let scaleAnimation:CABasicAnimation = CABasicAnimation(keyPath: "transform.scale")
    scaleAnimation.duration = 1.0
    scaleAnimation.repeatCount = 100
    scaleAnimation.autoreverses = true
    scaleAnimation.fromValue = 1.05;
    scaleAnimation.toValue = 0.95;
    button.layer.addAnimation(scaleAnimation, forKey: "scale")
}

2

这是一个关于坐标空间问题的旧线程,但如果有人需要帮助的话可以参考一下。

你只需要设置绘图空间和路径的空间即可解决。以下代码适用于我...

...只需将其放置在动画创建方法的开头(父视图内的方法中)即可。

// add animation to remap (without affecting other elements)
    let animationLayer = CALayer()
    layer?.addSublayer(animationLayer). // (don't use optional for iOS)

// set the layer origin to the center of the view (or any center point for the animation)
    animationLayer.bounds.origin .x = -self.bounds.size.width / 2.0
    animationLayer.bounds.origin .y = -self.bounds.height / 2.0

// make image layer with circle around the zero point
    let imageLayer = CAShapeLayer()
    animationLayer.addSublayer(imageLayer)

    let shapeBounds = CGRect(x: -bounds.size.width/2.0,
                             y:-bounds.size.height/2.0,
                             width: bounds.size.width,
                             height: bounds.size.height)

    imageLayer.path = CGPath(ellipseIn: shapeBounds, transform: nil)
    imageLayer.fillColor = fillColour


    // **** apply your animations to imageLayer here ****

这段代码在iOS和MacOS上均可正常运行,唯一的区别是在MacOS上需要使用可选项层。

(顺便提醒,动画结束后需要移除动画层!)


-1

我花了好几个小时按照中心点寻找如何在OSX上实现它,但是没有找到任何解决方案。最终我决定使用CATransform3DMakeTranslation移动图层并结合两种变换。

我的代码:

NSView *viewToTransform = self.view;
[viewToTransform setWantsLayer:YES];

viewToTransform.layer.sublayerTransform = CATransform3DConcat(CATransform3DMakeScale(-1.0f, -1.0f, 1.0f), CATransform3DMakeTranslation(viewToTransform.bounds.size.width, viewToTransform.bounds.size.height, 0));

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