Search code examples
swiftuiviewanimatewithdurationcompletion

UIView animate with completion block not working


I have the following small function wich contains two primary actions which I would like to occur. A three second animation, and then upon completion of that animation, another function call. What is happening, however, is that the line of code that calls another function is being executed before the UIView animation has completed.

func switchToNormalState() {

    print("Switching to Normal State")
    currentState = "normal"
    intervalCounter = intervalCounter + 1

    setVisualsForState()

    UIView.animateWithDuration(Double(normalDuration), animations: { () -> Void in
        self.ProgressBar.setProgress(1.0, animated: true)
        }, completion: { _ in
            self.switchToFastState()
    })

}

I have studied other similar posts looking for the solution but none of the solutions have solved my puzzle. What am I doing wrong in the completion block in order to make these actions a sequence and not simultaneous?


Solution

  • Assuming that ProgressBar is a UIProgressView, the setProgress method animates itself and doesn't need to be contained in a UIView.animateWithDuration call.

    This means the setProgress animation is probably longer than the duration you're putting in the UIView.animateWithDuration call, so self.switchToFastState() is being called when the UIView animation ends- before the setProgress animation completes.

    Solutions

    1. Change the duration. You can hack around this by finding/guessing the duration of the setProgress animation and using that as your UIView animation duration. This should mimic the behavior you are going for.

    2. Change the duration but use GCD. This is the same idea as above, but doesn't use the UIView animation method. You can see this question for how to use GCD.

    3. NSTimer or Subclassing. There are solutions here that use NSTimer or subclass UIProgressView.