Reputation: 1864
I've wrote this to apply heart beat animation to CAShapeLayer, after this worked fine, I need to implement it to be behind UIButton (btnTest) without scaling the UIButton or any other content.
@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)
}
the is this result gif
another solution was changing this line :
self.view.layer.add(theAnimation, forKey: nil)
to this :
btnLayer.add(theAnimation, forKey: nil)
the result of this was this :gif
Any ideas to solve this problem !
Upvotes: 0
Views: 690
Reputation: 4457
You can do it like this, just translate your layer alongside with scale animation. To do so you need to create a 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)
}
Upvotes: 1
Reputation: 131471
You want to animate your btnLayer
. The reason it's animating from the wrong place is probably that the layer's anchorPoint
is at 0,0, where it should be set to 0.5, 0.5.
Actually, I think the issue is where you put your btnLayer
. You should make it a sublayer of your button view's layer, and give it a frame that's the bounds of the button's layer:
btnTest.layer.addSublayer(btnLayer)
btnLayer.frame = btnTest.layer.bounds
Upvotes: 1
Reputation: 2099
1- First make the heart shape that will animate a UIView
let's name it heartView
.
2- self.view.addsubview(heartView)
(self.view
can be changed to any parent you want)
3- make an invisible button called heartButton
and give it the same frame of heartView
4- self.view.addsubview(heartButton)
(self.view
can be changed to any parent you want)
5- start the heartView animation.
The key point here is not to add the button on the animating view but on their parent (self.view
this case) since if the button
was on top of the heart and the heart is animating, the button will adopt the animation.
Hope this helps!
Upvotes: 0