从 iOS 8 开始提供
UIVisualEffectView
这种模糊效果的类,方便的同时也有些许局限性。
- 例如:无法修改模糊的程度、无法修改颜色。
1、先来看一下普通的效果:
2、实现模糊程度可控
模糊程度可控,是通过截停模糊效果的渲染而实现的。
import UIKit
open class BlurEffectView: UIVisualEffectView {
/// 模糊等级 (0 ~ 1)
open var blurLevel: Float = 1 {
didSet {
self.resumeAnimation()
var blurEffect: UIVisualEffect
if let effect = self.effect {
blurEffect = effect
} else {
blurEffect = UIBlurEffect(style: .extraLight)
}
self.effect = nil
UIView.animate(withDuration: TimeInterval(1 - blurLevel)) {
self.effect = blurEffect
}
self.pauseAnimation(delay: 0.3)
}
}
}
extension UIView {
/// 暂停动画
fileprivate func pauseAnimation(delay: Double) {
let time = delay + CFAbsoluteTimeGetCurrent()
let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, time, 0, 0, 0, { timer in
let layer = self.layer
let pausedTime = layer.convertTime(CACurrentMediaTime(), from: nil)
layer.speed = 0
layer.timeOffset = pausedTime
})
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.commonModes)
}
/// 继续动画
fileprivate func resumeAnimation() {
let pausedTime = layer.timeOffset
layer.speed = 1.0
layer.timeOffset = 0
layer.beginTime = layer.convertTime(CACurrentMediaTime(), from: nil) - pausedTime
}
}
3、模糊颜色
毛玻璃模糊颜色是通过一个私有的 API 来实现的。
import UIKit
open class ColorfulBlurEffectView: UIVisualEffectView {
fileprivate let blurEffect = (NSClassFromString("_UICustomBlurEffect") as! UIBlurEffect.Type).init()
open var colorTint: UIColor? {
get { return _value(forKey: "colorTint") as? UIColor }
set { _setValue(newValue, forKey: "colorTint") }
}
/// 默认 0
open var colorTintAlpha: CGFloat {
get { return _value(forKey: "colorTintAlpha") as! CGFloat }
set { _setValue(newValue, forKey: "colorTintAlpha") }
}
/// 默认 0
open var blurRadius: CGFloat {
get { return _value(forKey: "blurRadius") as! CGFloat }
set { _setValue(newValue, forKey: "blurRadius") }
}
/// 默认 1.0
open var scale: CGFloat {
get { return _value(forKey: "scale") as! CGFloat }
set { _setValue(newValue, forKey: "scale") }
}
public override init(effect: UIVisualEffect?) {
super.init(effect: effect)
prepare()
}
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
prepare()
}
fileprivate func prepare() {
scale = 1
}
}
extension ColorfulBlurEffectView {
fileprivate func _value(forKey key: String) -> Any? {
return blurEffect.value(forKeyPath: key)
}
fileprivate func _setValue(_ value: Any?, forKey key: String) {
blurEffect.setValue(value, forKeyPath: key)
self.effect = blurEffect
}
}
使用
colorEffectView.colorTint = #colorLiteral(red: 1, green: 0.1857388616, blue: 0.5733950138, alpha: 1)
colorEffectView.colorTintAlpha = 0.5
colorEffectView.blurRadius = 20