Search code examples
iosanimationcalayercaanimationcakeyframeanimation

CAAnimation: Syncing view's alpha with presentation layer's opacity


I'm animating the opacity of a view's layer using CAKeyframeAnimation, when app goes to background, the animation's removed, but I need to make the view's alpha to be the same as the animation, should I do:

view.alpha = view.layer.presentationLayer.opacity

???

Thanks!

Update:

I have three labels overlapping with each other, I used key frame animation to animate their opacity with different key frame values (for opacity) to mimic a crossfade animation. The problem is when app goes to background, the animations are removed (according to https://forums.developer.apple.com/thread/15796) so they all have alpha 1 and overlap with each other, that's why I wanted to sync the view with their presentation layer.


Solution

  • If the goal is to capture the opacity when the app goes in background, you can add an observer for UIApplicationDidEnterBackground, capture the opacity, cancel the animation, and set the alpha. E.g., in Swift:

    class ViewController: UIViewController {
    
        @IBOutlet weak var viewToAnimate: UIView!
    
        private var observer: NSObjectProtocol!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            observer = NotificationCenter.default.addObserver(forName: .UIApplicationDidEnterBackground, object: nil, queue: .main) { [weak self] notification in
                if let opacity = self?.viewToAnimate.layer.presentation()?.opacity {
                    self?.viewToAnimate.layer.removeAllAnimations()
                    self?.viewToAnimate.alpha = CGFloat(opacity)
                }
            }
        }
    
        deinit {
            NotificationCenter.default.removeObserver(observer)
        }
    
        // I'm just doing a basic animation, but the idea is the same whatever animation you're doing
    
        @IBAction func didTapButton(_ sender: Any) {
            UIView.animate(withDuration: 10) {
                self.viewToAnimate.alpha = 0
            }
        }
    
    }
    

    If your goal is to remember it even if the app is terminated, then you'd need to save this in persistent storage. But if your goal is to merely set the alpha while the app is suspended and/or running in background, the above is sufficient.