Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Animation stops if another view controller is presented #45

Open
tapizquent opened this issue Mar 5, 2019 · 5 comments
Open

Animation stops if another view controller is presented #45

tapizquent opened this issue Mar 5, 2019 · 5 comments

Comments

@tapizquent
Copy link

My controller includes a ImagePickerController, as soon as that displays, the background stops animating. Any ideas why? and how can i make it move again when the imagePicker dismisses

@tapizquent
Copy link
Author

NVM! I fixed it. I just added a var to your PastelView class to check whether is currently animating or not. and if its not, then I startAnimation() inside viewDidAppear.

open class PastelView: UIView {

    public var isAnimating: Bool = false   // This right here!

    private struct Animation {
        static let keyPath = "colors"
        static let key = "ColorChange"
    }

And then in

public func startAnimation() {
    self.isAnimating = true   // Here
    gradient.removeAllAnimations()
    setup()
    animateGradient()
}

extension PastelView: CAAnimationDelegate {
    public func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
        if flag {
             gradient.colors = currentGradientSet()
             animateGradient()
        } else {
            self.isAnimating = false
        }
     }
}

And lastly

override func viewDidLoad() {
    pastelView.startAnimation()
}
override func viewDidAppear(_ animated: Bool) {
    if !pastelView.isAnimating {
        pastelView.startAnimation()
    }
}

@tapizquent tapizquent changed the title Animation stops if another view controller is presented FIXED: Animation stops if another view controller is presented Mar 13, 2019
@tapizquent tapizquent changed the title FIXED: Animation stops if another view controller is presented Animation stops if another view controller is presented Mar 13, 2019
@tapizquent
Copy link
Author

NVM still opened because animation stops midway. No idea why

@Rida-ba
Copy link

Rida-ba commented Jan 1, 2020

Thanks it help me to figure it out.

I did like this in order to keep animation working (Using notification observer):

override func viewDidAppear(_ animated: Bool) {

    super.viewDidAppear(animated)
    /// Notification foreground observer
    NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground), name:          UIApplication.willEnterForegroundNotification, object: nil)
}

Then call this :

/// MARK: -  Custom Func
@objc func willEnterForeground() {
    /// Play animation
    if !pastelView.isAnimating {
        print("Play Animation")
        pastelView.startAnimation()
    }
}

In my case it works when my app will enter in foreground and will appear.
But you can use the same method with another view controller. (Using Notification and call objc func in another VC)

And don't forget to remove the observer :

NotificationCenter.default.removeObserver(self, name: UIApplication.willEnterForegroundNotification, object: nil)

I hope it works for you.

Happy New Year !!!!

@ucelme
Copy link

ucelme commented Feb 13, 2020

Can you provide the full code to fix animations? I get Use of unresolved identifier 'pastelView'

@DorukhanArslan
Copy link

There is no need to hold an extra property (isAnimating) in base class. This will handle all cases:

final class AnimatedGradientViewController: UIViewController {

    private lazy var animatedGradientView: PastelView = {
        ...
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        // 1. Starts animation when view controller is loaded initially.
        animatedGradientView.startAnimation()

        // Insert animated gradient view as subview once.
        view.insertSubview(animatedGradientView, at: 0)

        // Add 'willEnterForeground' notification observer once. First launch does not count.
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(willEnterForeground),
            name: UIApplication.willEnterForegroundNotification,
            object: nil)
    }

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

        // View is not appeared at the end of neither dismiss or pop, it means view is seen after
        // dismiss or pop of a view controller.
        guard !isBeingPresented && !isMovingToParent else {
            return
        }

        // 2. Starts animation if view controller is seen after dismiss or pop.
        animatedGradientView.startAnimation()
    }

    @objc
    private func willEnterForeground() {
        // 3. Starts animation if app was entered background, e.g. locked or gone to home screen.
        animatedGradientView.startAnimation()
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants