kaandedeoglu / KDCircularProgress

A circular progress view with gradients written in Swift
MIT License
1.21k stars 217 forks source link

Circle animation immidiatelly finish when you press home button and get back #33

Closed yakoobs closed 8 years ago

yakoobs commented 8 years ago
  1. Start animation
  2. Press home button
  3. Quickly get back to the app
  4. Animation should be continuosly displayed but the effect is that the circle is fully drawn and animation has finished

You can reproduce it on your example project

nazrdogan commented 8 years ago

+1

kaandedeoglu commented 8 years ago

@yakoobs @nazrdogan I'll take a look at this next week. Thank you for bringing this up and sorry for replying this late!

ruixingchen commented 8 years ago

faced this problem, too

MarkHendriks commented 8 years ago

@kaandedeoglu Also having this issue. Any idea on how to fix it? Thanks!

ruixingchen commented 8 years ago

now I use a Timer to control the progress, it works but I have to handle the Timer.

Insofan commented 8 years ago

@ruixingchen How to fix it?

nazrdogan commented 8 years ago

its not solution but for alternative progress.https://github.com/kentya6/KYCircularProgress

MarkHendriks commented 8 years ago

@nazrdogan @Insofan In my use case I'm using it as a timer function, counting down from 1 min for example. I think the bug is in progress.angle that always returns 360 degrees. I solved this by running a function when the app gets resumed. The basics:

override func viewDidLoad() {

    // Runs when app resumes
    NotificationCenter.default.addObserver(self, selector: #selector(self.applicationEnteredForeground), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)

}

Basic Timer in this example

    var time: Double = 60

    var timer = Timer()
    timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(TimerViewController.increaseTimer), userInfo: nil, repeats: true)

    // Increase Timer
    func increaseTimer() {

        time -= 1

    }

Now I'm manually setting the progress for the remaining time. time is my Timer object that counts down every second and runs in the background. For example when you resume there are 30 seconds left out of the original 60 seconds.

// When app resumes set progress manually
func applicationEnteredForeground(_ notification: Notification) {

    // The amount of time you started with
    let startTime: Double = 60     

    // Substract the start time from the running timer
    let remainTime = startTime - time

    // Set progress manually
    progress.animate(fromAngle:(360*(remainTime/startTime)), toAngle: 360, duration: time) { completed in }

    }

}

This would render the progress to 50% and continue onwards. You would have to add some additional functionally such as to see if the Timer is still running. It may not be the prettiest solution, but it works all the time and passed App Review.

Insofan commented 8 years ago

@nazrdogan Thank you.Have u ever try it in app.I only want a simple circlular count down timer can run in background. @MarkHendriks Thx a lot.I will try this solution.

yakoobs commented 8 years ago

I think I found it! Just put the line in the code: (...)

let animation = CABasicAnimation(keyPath: "angle") animation.fromValue = fromAngle animation.toValue = toAngle animation.duration = animationDuration animation.delegate = self animation.removedOnCompletion = false //THIS ONE :) angle = toAngle animationCompletionBlock = completion progressLayer.addAnimation(animation, forKey: "angle") (...)

MarkHendriks commented 8 years ago

@yakoobs Can confirm this works! Swift 3:

animation.isRemovedOnCompletion = false
progressLayer.add(animation, forKey: "angle")
kaandedeoglu commented 8 years ago

@yakoobs @MarkHendriks can you please submit a PR so I can test & merge it if it works as intended?

Insofan commented 8 years ago

@yakoobs Greate work! @kaandedeoglu it works well

func animated(min: Int){ progress.animate(fromAngle: 0, toAngle: 360, duration: TimeInterval(min_60), completion: nil) let animation = CABasicAnimation(keyPath: "angle") animation.fromValue = 0 animation.toValue = 360 animation.duration = TimeInterval(min_60) animation.delegate = self animation.isRemovedOnCompletion = false //THIS ONE :) let angle = 360 progress.layer.add(animation, forKey: "angle") }

yakoobs commented 8 years ago

Fixed on the master branch. Issue closed