在iOS中,通常是运用UIVisualEffectView+UIBlurEffect完成毛玻璃作用,可是苹果并没有供给修正含糊度的API。网上许多都是修正其alpha值完成所谓“含糊度改动”的作用,这种只是自欺欺人的做法,并非真的修正了含糊度。

Demo地址:JPBlurView

完成毛玻璃动画

尽管没有修正含糊度的API,可是有毛玻璃的展现和躲藏动画:

let effectView = UIVisualEffectView(effect: nil)
// 毛玻璃展现动画
UIView.animate(withDuration: 0.3) {
    effectView.effect = UIBlurEffect(style: systemThinMaterialDark)
}
// 毛玻璃躲藏动画
UIView.animate(withDuration: 0.3) {
    effectView.effect = nil
}

只要对UIVisualEffectVieweffect特点的setter办法包裹一层动画,就能够完成毛玻璃动画了:

【iOS】实现可自定义模糊度的毛玻璃及动画效果

操控毛玻璃动画进展

仔细观察,这个毛玻璃作用从无到有这个进程,不便是含糊度从0到1的进程吗?那么只要能操控这个毛玻璃动画的进展,就相当于自界说含糊度了。这种情况便是UIViewPropertyAnimator上台的时候了。

UIViewPropertyAnimator是iOS中的一个动画类,用于创建和办理视图动画。它供给了一种强壮且灵敏的方式来创建自界说的交互式动画:能够界说动画的起始状况、完毕状况和持续时间,还能够经过操控动画的进展来完成交互性。

更多的介绍这儿就不赘述了,网上许多资料能够参阅,这儿简略完成一下:

let effectView = UIVisualEffectView(effect: nil)
animator = UIViewPropertyAnimator(duration: 0, curve: .linear, animations: { [weak effectView] in
    effectView?.effect = UIBlurEffect(style: systemThinMaterialDark)
})
animator.fractionComplete = 0

这样,经过修正animatorfractionComplete特点然后完成可自界说含糊度的毛玻璃作用了:

【iOS】实现可自定义模糊度的毛玻璃及动画效果

完成可自界说含糊度动画

尽管UIViewPropertyAnimator能够操控动画进展,可是并不能完成自界说含糊度的动画。

例如假如想经过UIViewPropertyAnimator完成含糊度0.2~0.7的动画是不行的,一旦动画开始了就会直达1.0,不能履行到某个值主动停下,除非对fractionComplete特点进行监听,我个人觉得这种做法很费事。

有没有一种模拟动画并且能回来动画进展的办法呢?这样我就能经过这个实时动画进展更新fractionComplete特点就能够了。

很幸运,有!那便是pop!

POPPropertyAnimation有个POPAnimatableProperty特点,能够实时监听动画的进展,而且是带有动画曲线的进展,并且不需求真的对某个视图添加动画,简略来说便是能模拟一个动画,非常好用。

我这儿选择运用POPBasicAnimation来完成,由于POPBasicAnimation能自界说动画时长和动画曲线,能满足根本的动画作用:

// 创建一个基类专门来监听进展
let animObserver = NSObject()
let animation = POPBasicAnimation()
animation.fromValue = 0.2
animation.toValue = 0.7
animation.duration = 0.3
animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
// 监听实时动画进展
animation.property = POPAnimatableProperty.property(withName: "JPProperty") { [weak animator] prop in
    prop?.writeBlock = { (_, values) in
        guard let values = values else { return }
        let value = values[0]
        // 改写含糊度
        animator?.fractionComplete = value
    }
} as? POPAnimatableProperty
// 开始(模拟)动画
animObserver.pop_add(animation, forKey: "JPAnimation")

这样就能完成可自界说含糊度动画了:

【iOS】实现可自定义模糊度的毛玻璃及动画效果

需求留意的当地

  1. 一旦运用UIViewPropertyAnimator暂停了动画(没有敞开或还没完毕),有必要在退出页面前让动画完毕,否则会溃散!
animator.stopAnimation(true)
  1. 同样,假如运用UIViewPropertyAnimator暂停了动画,App一旦进入后台模式就会失效(挂起时不会),回来前台时需求重新设置一下:
@objc func willEnterForegroundHandle() {
    guard animator.state != .active else { return }
    animator.stopAnimation(true)
    resetAnimator()
}

完成可交互的毛玻璃布景

结合上面的做法,就能够在阅读大图的布景完成这种可交互的毛玻璃作用了:

  • 经过手指进行交互,依据手指滑动间隔修正含糊度;
  • 松开手指复原/封闭,动画完成含糊度从0.x到1.0/0.0的进程。

Demo地址:JPBlurView