Animate the Fractioncomplete of Uiviewpropertyanimator for Blurring the Background

Animate the fractionComplete of UIViewPropertyAnimator for blurring the background

It seems that fractionComplete has a bug (my question on Stackoverflow: UIViewPropertyAnimator does not update the view when expected), rdar://30856746. The property only sets the state from inactive to active, but does not update the view, because (I assume) there is another internal state that does not trigger.

To workaround the problem you can do this:

animator.startAnimation() // This will change the `state` from inactive to active
animator.pauseAnimation() // This will change `isRunning` back to false, but the `state` will remain as active

// Now any call of `fractionComplete` should update your view correctly!
animator.fractionComplete = /* your value here */

Here is a playground snippet to play around:

let liveView = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 50))
liveView.backgroundColor = .white

PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = liveView

let square = UIView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
square.backgroundColor = .red

liveView.addSubview(square)

let animator = UIViewPropertyAnimator.init(duration: 5, curve: .linear)

animator.addAnimations {

square.frame.origin.x = 350
}

let blurView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
blurView.frame = liveView.bounds

liveView.addSubview(blurView)

animator.addAnimations {

blurView.effect = nil
}

// If you want to restore the blur after it was animated, you have to
// safe a reference to the effect which is manipulated
let effect = blurView.effect

animator.addCompletion {
// In case you want to restore the blur effect
if $0 == .start { blurView.effect = effect }
}

animator.startAnimation()
animator.pauseAnimation()

DispatchQueue.main.asyncAfter(deadline: .now() + 2) {

animator.fractionComplete = 0.5
}

DispatchQueue.main.asyncAfter(deadline: .now() + 4) {

// decide the direction you want your animation to go.
// animator.isReversed = true
animator.startAnimation()
}

Swift UIViewPropertyAnimator automatically plays when leaving app

I reproduced your issue, and confirm this behavior, but I doubt it's a bug. Property animator just returns from paused state to active and runs animation. To overcome it you have to stop it and then finish in current fraction of the state (respective states are described in docs). One more issue here - somehow stopping it right after setting fractionComplete stops it at 0 so you have to wait a while (very short). Try this code under your "blurAction":

    self.animator?.startAnimation()
self.animator?.pauseAnimation()
self.animator?.fractionComplete = CGFloat(0.1)

DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
self.animator?.pauseAnimation()
self.animator?.stopAnimation(true)
self.animator?.finishAnimation(at: .current)
}

I verified it works for background/foreground app lifecycle change.

iOS: Transition animation with UIBlurEffect?

You are not seeing any animation because you didn't do anything that animates. UIView animation relies on the use of animatable properties of an existing view. You aren't animating any properties: you are merely calling addSubview:.

UIView.animation not animating colour change

You can try this code

 UIView.transition(with: myLabel, duration: 0.4, options: .transitionCrossDissolve, animations: {
self.myLabel.backgroundColor! = UIColor.init(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
}) { (finish) in
}


Related Topics



Leave a reply



Submit