如何防止CABasicAnimation扩展UIView内的所有内容?

时间:2017-07-28 13:14:31

标签: ios swift3 uibutton cashapelayer cabasicanimation

我已经写过这个将心跳动画应用到CAShapeLayer,在此工作正常后,我需要将其实现为UIButton(btnTest),而不缩放UIButton或任何其他内容。

@IBOutlet weak var btnTest: UIButton!

let btnLayer = CAShapeLayer()

override func viewDidLoad() {
    super.viewDidLoad()
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    btnTest.layer.removeAllAnimations()

    let ovalPath = UIBezierPath(arcCenter: CGPoint(x: btnTest.frame.midX, y: btnTest.frame.midY), radius: 100, startAngle: 0*(CGFloat.pi / 180), endAngle: 360*(CGFloat.pi / 180), clockwise: true)

    btnLayer.path = ovalPath.cgPath
    btnLayer.fillColor = UIColor.red.cgColor
    btnLayer.contentsGravity = "center"
    btnLayer.opacity = 0.3
    self.view.layer.addSublayer(btnLayer)

    let theAnimation = CABasicAnimation(keyPath: "transform.scale.xy")
    theAnimation.duration       = 0.75
    theAnimation.repeatCount    = Float.infinity
    theAnimation.autoreverses   = true
    theAnimation.fromValue      = 1.0
    theAnimation.toValue        = 1.2
    theAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
    self.view.layer.add(theAnimation, forKey: nil)
}

结果是gif

另一个解决方案正在改变这一行:

self.view.layer.add(theAnimation, forKey: nil)

到此:

btnLayer.add(theAnimation, forKey: nil)

结果如下:gif

解决这个问题的任何想法!

3 个答案:

答案 0 :(得分:1)

您希望为btnLayer设置动画。它从错误的地方动画的原因可能是图层的anchorPoint位于0,0,应该设置为0.5,0.5。

编辑:

实际上,我认为问题出在您放置btnLayer的位置。你应该把它作为按钮视图图层的子图层,并给它一个框架,它是按钮图层的边界:

btnTest.layer.addSublayer(btnLayer)
btnLayer.frame = btnTest.layer.bounds

答案 1 :(得分:1)

你可以这样做,只需将你的图层与缩放动画一起翻译。为此,您需要创建一个CAAnimationGroup。

   override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    btnTest.layer.removeAllAnimations()

    let ovalPath = UIBezierPath(arcCenter: CGPoint(x: btnTest.frame.midX, y: btnTest.frame.midY), radius: 100, startAngle: 0*(CGFloat.pi / 180), endAngle: 360*(CGFloat.pi / 180), clockwise: true)

    btnLayer.path = ovalPath.cgPath
    btnLayer.fillColor = UIColor.red.cgColor
    btnLayer.anchorPoint = CGPoint.init(x: 0.5, y: 0.5)
    btnLayer.contentsGravity = "center"
    btnLayer.opacity = 0.3
    self.view.layer.addSublayer(btnLayer)

    let theAnimation = CABasicAnimation(keyPath: "transform.scale.xy")
    theAnimation.fromValue      = 1.0
    theAnimation.toValue        = 1.2

    let theAnimationTranslationX = CABasicAnimation(keyPath: "transform.translation.x")
    theAnimationTranslationX.fromValue      = btnTest.bounds.minX
    theAnimationTranslationX.toValue        = btnTest.bounds.minX - 40

    let theAnimationTranslationY = CABasicAnimation(keyPath: "transform.translation.y")
    theAnimationTranslationY.fromValue      = btnTest.bounds.minY
    theAnimationTranslationY.toValue        = btnTest.bounds.minY - 80


    let animationGroup = CAAnimationGroup.init()
    animationGroup.duration       = 0.75
    animationGroup.repeatCount    = Float.infinity
    animationGroup.autoreverses   = true
    animationGroup.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
    animationGroup.animations = [theAnimation,theAnimationTranslationX,theAnimationTranslationY]

    btnLayer.add(animationGroup, forKey: nil)
}

答案 2 :(得分:0)

1-首先制作一个将UIView heartView命名为self.view.addsubview(heartView)的动画的心形。

2- self.viewheartButton可以更改为您想要的任何父级)

3-制作一个名为heartView的隐藏按钮,并为其提供相同的self.view.addsubview(heartButton)

框架

4- self.viewself.view可以更改为您想要的任何父级)

5-启动heartView动画。

这里的关键点是不要在动画视图上添加按钮,而是在父视图上添加按钮(button这种情况),因为如果<!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <item name="android:windowActionBarOverlay">false</item> <item name="android:textColorPrimary">#000000</item> </style> <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" /> <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" /> </resources> 位于心脏之上并且心脏是动画,按钮将采用动画。

希望这有帮助!