【问题标题】:CABasicAnimation not scaling around centerCABasicAnimation 不围绕中心缩放
【发布时间】:2017-03-14 13:25:58
【问题描述】:

我想同时执行不透明度和缩放效果,我的动画效果很好,但它的位置不合适。我想在中心执行动画。 这是我的代码。

    btn.backgroundColor = UIColor.yellowColor()
    let stroke =  UIColor(red:236.0/255, green:0.0/255, blue:140.0/255, alpha:0.8)
    let pathFrame = CGRectMake(24, 13, btn.bounds.size.height/2, btn.bounds.size.height/2)

    let circleShape1 = CAShapeLayer()
    circleShape1.path = UIBezierPath(roundedRect: pathFrame, cornerRadius: btn.bounds.size.height/2).CGPath
    circleShape1.position = CGPoint(x: 2, y: 2)
    circleShape1.fillColor = stroke.CGColor
    circleShape1.opacity = 0

    btn.layer.addSublayer(circleShape1)

    circleShape1.anchorPoint = CGPoint(x: 0.5, y: 0.5)

    let scaleAnimation = CABasicAnimation(keyPath: "transform.scale")
    scaleAnimation.fromValue = NSValue(CATransform3D: CATransform3DIdentity)
    scaleAnimation.toValue = NSValue(CATransform3D: CATransform3DMakeScale(2.0, 2.0, 1))

    let alphaAnimation = CABasicAnimation(keyPath: "opacity")
    alphaAnimation.fromValue = 1
    alphaAnimation.toValue = 0

    CATransaction.begin()
    let animation = CAAnimationGroup()
    animation.animations = [scaleAnimation, alphaAnimation]
    animation.duration = 1.5
    animation.repeatCount = .infinity
    animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    circleShape1.addAnimation(animation, forKey:"Ripple")
    CATransaction.commit()

【问题讨论】:

  • 这里的一个关键问题是,您无法一次性创建子图层、将其添加到界面并为其设置动画。只有当图层已经在界面中时,才必须执行动画。

标签: ios iphone swift core-animation cabasicanimation


【解决方案1】:

问题在于您没有正确处理帧。你说:

 let circleShape1 = CAShapeLayer()

但是你忘了给circleShape1一个框架!因此,它的大小为零,当你为它设置动画时会发生非常奇怪的事情。您在下一行的工作应该是为circleShape1 分配一个框架。示例:

circleShape1.frame = pathFrame

这可能是也可能不是正确的框架;可能不是。但你需要弄清楚这一点。

然后,您需要根据形状层的边界来修复贝塞尔路径的框架:

circleShape1.path = UIBezierPath(roundedRect: circleShape1.bounds // ...

【讨论】:

  • 感谢您回答我的问题。我尝试设置框架,但动画看起来像从左到右下角。我想要动画执行中心。
【解决方案2】:

我从未使用过子图层,所以我会使用子视图来代替,这会使代码更容易:

btn.backgroundColor = UIColor.yellow

let circleShape1 = UIView()

circleShape1.frame.size = CGSize(width: btn.frame.height / 2, height: btn.frame.height / 2)
circleShape1.center = CGPoint(x: btn.frame.width / 2, y: btn.frame.height / 2)
circleShape1.layer.cornerRadius = btn.frame.height / 4
circleShape1.backgroundColor = UIColor(red:236.0/255, green:0.0/255, blue:140.0/255, alpha:0.8)
circleShape1.alpha = 1

btn.addSubview(circleShape1)

UIView.animate(withDuration: 1,
               delay: 0,
               options: [.repeat, .curveLinear],
               animations: {
                    circleShape1.transform = CGAffineTransform(scaleX: 5, y: 5)
                    circleShape1.alpha = 0.4
               }, completion: nil)

【讨论】:

  • 感谢您回答我的问题,但我想要继续动画,但您的回答动画只有一次。执行。
  • @jigneshVadadoriya 我的答案是连续动画,它在 UIView.animate 中有 .repeat 作为选项
  • 我有检查,但它没有执行继续动画,同时提供 .repeat 作为选项。
【解决方案3】:

您需要创建具有 {0,0} 位置的路径框架,并为图层设置正确的框架:

let pathFrame = CGRectMake(0, 0, btn.bounds.size.height/2, btn.bounds.size.height/2)
....
circleShape1.frame = CGRect(x: 0, y: 0, width: pathFrame.width, height: pathFrame.height)
circleShape1.position = CGPoint(x: 2, y: 2)

如果您想创建具有 {13,24} 位置的路径,您需要更改图层的宽度和高度。你的形状应该在图层的中心。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    • 2013-11-15
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 2021-04-26
    • 1970-01-01
    相关资源
    最近更新 更多