1

I wrote the code but I can not understand why it does not work...

func animate(vc: UIView) {
    vc.layer.shadowColor = #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)
    vc.layer.shadowRadius = 5
    vc.layer.shadowOffset = CGSize(width: 0, height: 0)
    let animationX = CABasicAnimation()
    animationX.keyPath = "shadowOffset"
    animationX.fromValue = vc.layer.shadowOffset
    animationX.toValue = CGSize(width: 10, height: 10)
    animationX.duration = 1
    vc.layer.add(animationX, forKey: animationX.keyPath)
}

@IBAction func buttonTapped(_ sender: UIButton) {
  animate(vc: sender)
}

Does anyone know how this works?

1 Answers1

1

Couple of things missing

  1. shadowPath
  2. shadowOpacity
        vc.layer.masksToBounds = false
        vc.layer.shadowColor = #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)
        vc.layer.shadowRadius = 5
        vc.layer.shadowOffset = CGSize(width: 0, height: 0)
        vc.layer.shadowPath = UIBezierPath(rect: vc.bounds).cgPath
        vc.layer.shadowOpacity = 1.0
        let animationX = CABasicAnimation()
        animationX.keyPath = "shadowOffset"
        animationX.fromValue = vc.layer.shadowOffset
        animationX.toValue = CGSize(width: 10, height: 10)
        animationX.duration = 1
        vc.layer.add(animationX, forKey: animationX.keyPath)

By default shadowOpacity is 0.

Final O/P

enter image description here

EDIT:

If you want shadow to persist in its position even after animation specify

  1. fillMode
  2. isRemovedOnCompletion

final code will look like

func animate(vc: UIView) {
        vc.layer.masksToBounds = false
        vc.layer.shadowColor = #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)
        vc.layer.shadowRadius = 5
        vc.layer.shadowOffset = CGSize(width: 0, height: 0)
        vc.layer.shadowPath = UIBezierPath(rect: vc.bounds).cgPath
        vc.layer.shadowOpacity = 1.0
        let animationX = CABasicAnimation()
        animationX.keyPath = "shadowOffset"
        animationX.fromValue = vc.layer.shadowOffset
        animationX.toValue = CGSize(width: 10, height: 10)
        animationX.duration = 1
        animationX.fillMode = .forwards
        animationX.isRemovedOnCompletion = false
        vc.layer.add(animationX, forKey: animationX.keyPath)
    }

Final O/P looks like:

enter image description here

Sandeep Bhandari
  • 19,999
  • 5
  • 45
  • 78
  • Sandeep Bhandari Thank you very much now I understand how it works – Nikolay Nikolaenko May 23 '20 at 17:09
  • @nikolay-nikolaenko: Please accept my answer if it helped you :) – Sandeep Bhandari May 23 '20 at 18:53
  • Hello @SandeepBhandari, could you help me with the same problem but using the shadowPath? I would need to animate a UIView vertical growing with its shadow border: https://stackoverflow.com/questions/65492182/how-to-animate-the-shadow-border-of-an-uiview-at-the-same-time-its-content-grows – Andoni Da Silva Dec 29 '20 at 14:38