这是一个 有趣的小实验, 展示了 Swift 协议扩展 的强大功能,无需开发人员开销即可将 CIGaussianBlur 核心图像过滤器应用于任何 UIView。可以扩展代码以应用任何 Core Image 过滤器,例如半色调屏幕或颜色调整。
Blurable 是一个简单的协议,它从 UIView 中借用了一些方法和变量:
var layer: CALayer { get }
var subviews: [UIView] { get }
var frame: CGRect { get }
func addSubview(view: UIView)
func bringSubviewToFront(view: UIView)
...并添加了一些自己的:
显然,它只是一个协议,它自己并不能做太多事情。但是,通过添加扩展,我可以引入默认功能。此外,通过扩展 UIView 实现 Blurable, 从分段控件到水平滑块的每个组件都可以模糊:
var layer: CALayer { get }
var subviews: [UIView] { get }
var frame: CGRect { get }
func addSubview(view: UIView)
func bringSubviewToFront(view: UIView)
Blurable 的机制
获得 UIView 的模糊表示非常简单:我需要开始图像上下文,使用视图层的 renderInContext 方法渲染到上下文中,然后从上下文中获取 UIImage:
var layer: CALayer { get }
var subviews: [UIView] { get }
var frame: CGRect { get }
func addSubview(view: UIView)
func bringSubviewToFront(view: UIView)
填充图像后,将高斯模糊应用到它是一个相当标准的工作流程:
var layer: CALayer { get }
var subviews: [UIView] { get }
var frame: CGRect { get }
func addSubview(view: UIView)
func bringSubviewToFront(view: UIView)
模糊图像将大于其输入图像,因此我需要明确说明我在 createCGImage 中需要的大小。
下一步是将 UIImageView 添加到我的视图并隐藏所有其他视图。我已将 UIImageView 子类化为 BlurOverlay,以便在删除它时,我可以确定我没有删除现有的 UIImageView:
var layer: CALayer { get }
var subviews: [UIView] { get }
var frame: CGRect { get }
func addSubview(view: UIView)
func bringSubviewToFront(view: UIView)
说到去模糊,我想确保最后一个子视图是我的 BlurOverlay 之一,删除它并取消隐藏现有视图:
var layer: CALayer { get }
var subviews: [UIView] { get }
var frame: CGRect { get }
func addSubview(view: UIView)
func bringSubviewToFront(view: UIView)
最后,要查看 UIView 当前是否模糊,我只需要查看其最后一个子视图是否为 BlurOverlay:
var layer: CALayer { get }
var subviews: [UIView] { get }
var frame: CGRect { get }
func addSubview(view: UIView)
func bringSubviewToFront(view: UIView)
模糊 UIView
要模糊和去模糊,只需在 UIView 上调用 blur() 和 unBlur() :
var layer: CALayer { get }
var subviews: [UIView] { get }
var frame: CGRect { get }
func addSubview(view: UIView)
func bringSubviewToFront(view: UIView)
源代码
与往常一样, 该项目的源代码可在我的 GitHub 存储库中获取 。享受!