为 UIViewPropertyAnimator 的 fractionComplete 设置动画以模糊背景
Animate the fractionComplete of UIViewPropertyAnimator for blurring the background
所以我使用新的 UIViewPropertyAnimator 和 UIVisualEffectView 来实现与 Spotlight 搜索相同的效果,当您在主屏幕上向下滚动时它会模糊背景。
我正在使用 fractionComplete 属性 来设置平移 UIView 时模糊程度的百分比。
animator = UIViewPropertyAnimator(duration: 1, curve: .linear) {
self.blurEffectView.effect = nil
}
模糊度的变化范围为 0.0 - 1.0。
animator?.fractionComplete = blurValue
但是,当我取消平移手势时,我希望模糊从原来的位置恢复为无模糊(例如 ~ -> 1.0),持续时间约为 0.4 毫秒。
现在我只是在取消平移手势时将 fractionComplete 设置为 1.0。相反,我想为它制作动画。
我试过 UIView.animate(withDuration.. 但它不影响 UIViewPropertyAnimators fractionComplete,这是模糊 UIVisualEffectView 的唯一方法。
有什么想法吗?
似乎fractionComplete
有一个错误(我在Whosebug上的问题:UIViewPropertyAnimator does not update the view when expected), rdar://30856746。属性只设置状态从inactive
到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 */
这里有一个 playground 片段可以玩:
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 [=11=] == .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()
}
如果您仍在寻找一种无需使用滑块或手势即可真正为 fractionComplete 制作动画的方法,我对使用 CADisplayLink 的结果非常满意。你可以在这里看到我的结果:https://gist.github.com/vegather/07993d15c83ffcd5182c8c27f1aa600b
我使用延迟循环来减少“fractionComplete”
func resetAnimator(){
let duration = 1.0 / 60.0
if self.animator.fractionComplete > 0 {
self.animator.fractionComplete -= 0.06
delay(duration, closure: {
self.resetAnimator()
})
}
}
func delay(_ delay:Double, closure:@escaping ()->()) {
DispatchQueue.main.asyncAfter(
deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: closure)
}
所以我使用新的 UIViewPropertyAnimator 和 UIVisualEffectView 来实现与 Spotlight 搜索相同的效果,当您在主屏幕上向下滚动时它会模糊背景。
我正在使用 fractionComplete 属性 来设置平移 UIView 时模糊程度的百分比。
animator = UIViewPropertyAnimator(duration: 1, curve: .linear) {
self.blurEffectView.effect = nil
}
模糊度的变化范围为 0.0 - 1.0。
animator?.fractionComplete = blurValue
但是,当我取消平移手势时,我希望模糊从原来的位置恢复为无模糊(例如 ~ -> 1.0),持续时间约为 0.4 毫秒。
现在我只是在取消平移手势时将 fractionComplete 设置为 1.0。相反,我想为它制作动画。
我试过 UIView.animate(withDuration.. 但它不影响 UIViewPropertyAnimators fractionComplete,这是模糊 UIVisualEffectView 的唯一方法。
有什么想法吗?
似乎fractionComplete
有一个错误(我在Whosebug上的问题:UIViewPropertyAnimator does not update the view when expected), rdar://30856746。属性只设置状态从inactive
到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 */
这里有一个 playground 片段可以玩:
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 [=11=] == .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()
}
如果您仍在寻找一种无需使用滑块或手势即可真正为 fractionComplete 制作动画的方法,我对使用 CADisplayLink 的结果非常满意。你可以在这里看到我的结果:https://gist.github.com/vegather/07993d15c83ffcd5182c8c27f1aa600b
我使用延迟循环来减少“fractionComplete”
func resetAnimator(){
let duration = 1.0 / 60.0
if self.animator.fractionComplete > 0 {
self.animator.fractionComplete -= 0.06
delay(duration, closure: {
self.resetAnimator()
})
}
}
func delay(_ delay:Double, closure:@escaping ()->()) {
DispatchQueue.main.asyncAfter(
deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: closure)
}