shu223 / Pulsator

Pulse animation for iOS
MIT License
1.42k stars 160 forks source link

Pulsator stops working after presenting a viewcontroller then dismissing it #15

Closed DeepAnchor closed 3 years ago

DeepAnchor commented 7 years ago

Hello,

I'm encountering an issue where if I have a pulsator started on a viewcontroller, then I present another viewcontroller and dismiss it, the pulse animation no longer shows. I forked the demo project to demonstrate the problem here.

Just click the button to present the viewcontroller, then dismiss it and you can see that the pulse stops. Any suggestions on how to fix this?

jaimeagudo commented 7 years ago

Also after calling stop it's not possible to start again on my tests but unfortunately cannot dig further

H2wk commented 7 years ago

@DeepAnchor there is a floor in your fork as you never reinitialize the Pulsator when you dismiss the view. Your example only has the start method on the:

override func viewDidLoad() { super.viewDidLoad() sourceView.layer.superlayer?.insertSublayer(pulsator, below: sourceView.layer) setupInitialValues() pulsator.start() }

it should be: override func viewDidAppear(_ animated: Bool) { setupInitialValues() pulsator.start() }

Seem to work ok for me to run it this way in your demo/fork

H2wk commented 7 years ago

So there seems to be an issue with the layer element of this control. I was able to get it to display again from a 'Notification' by using a timer:

Timer.scheduledTimer(timeInterval: 1, target: self, selector:  #selector(startPulsing),userInfo: nil, repeats: false)

I also found that by declaring the value varibale as an optional and re inititlizing after each stop seemed to do the trick. Like so:

var pulsator : Pulsator? = nil

func startPulsing(){
        pulsator = Pulsator()
        pulsator?.numPulse = 3
        pulsator?.radius = (180)
        pulsator?.animationDuration = 5
        pulsator?.opacity = 0.7
        pulsator?.backgroundColor = UIColor.greyColor.cgColor

        pulsatorViewPlaceholder.layer.addSublayer(pulsator!)
        pulsator?.start()
    }

 func stopPulsing(){
        pulsator?.stop()
        pulsator = nil
}
punithbm commented 7 years ago

Is there any other ways to do it.. because calling it in view did load its not working .. and like this not working var pulsator : Pulsator? = nil

H2wk commented 7 years ago

@Punith1234 i found i had to put a 2 sec delay on calling the init of the pulsator. As is you call start before it is the top view it would not run for me.

atillaozder commented 7 years ago

If you want that the pulse animation will not stop even if you change the current view and then go back to the main view, I think you just need to access setupAnimationGroup method in Pulsator.swift file

fileprivate func setupAnimateionGroup() {
        let scaleAnimation = CABasicAnimation(keyPath: "transform.scale.xy")
        scaleAnimation.fromValue = fromValueForRadius
        scaleAnimation.toValue = 1.0
        scaleAnimation.duration = animationDuration

        let opacityAnimation = CAKeyframeAnimation(keyPath: "opacity")
        opacityAnimation.duration = animationDuration
        opacityAnimation.values = [alpha, alpha * 0.5, 0.0]
        opacityAnimation.keyTimes = [0.0, NSNumber(value: keyTimeForHalfOpacity), 1.0]

        animationGroup = CAAnimationGroup()
        animationGroup.animations = [scaleAnimation, opacityAnimation]
        animationGroup.duration = animationDuration + pulseInterval
        animationGroup.repeatCount = repeatCount
        if let timingFunction = timingFunction {
            animationGroup.timingFunction = timingFunction
        }
        animationGroup.delegate = self
    }

and add the following line to inside the method.

animationGroup.isRemovedOnCompletion = false

Because the animation does not stop while you are travelling around, it seems better i think. However there could be a problem about memory load. I don't know.