似乎fractionComplete
有一个错误(我在 Stackoverflow 上的问题:UIViewPropertyAnimator does not update the view when expected),rdar://30856746。该属性仅将状态设置为inactive
to active
,但不会更新视图,因为(我假设)还有另一个不会触发的内部状态。
要解决此问题,您可以执行以下操作:
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 */
这是一个可以玩的游乐场片段:
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()
}