Blurable源码解析:从objc_setAssociatedObject到CIGaussianBlur的完整流程

Blurable源码解析:从objc_setAssociatedObject到CIGaussianBlur的完整流程

【免费下载链接】Blurable Apply a Gaussian Blur to any UIView with Swift Protocol Extensions 【免费下载链接】Blurable 项目地址: https://gitcode.com/gh_mirrors/bl/Blurable

Blurable是一个基于Swift Protocol Extensions实现的UIView高斯模糊工具,通过简单的API调用即可为任何UIView添加平滑的模糊效果。本文将深入解析其核心实现原理,从关联对象存储到Core Image模糊滤镜的完整工作流程。

核心架构:Protocol Extension实现无侵入扩展

Blurable的核心设计采用了Swift的协议扩展(Protocol Extension)模式,通过创建Blurable协议并为UIView添加默认实现,实现了对所有UI组件的无侵入式模糊功能扩展。

protocol Blurable {
    // 协议定义...
    func blur(blurRadius blurRadius: CGFloat)
    func unBlur()
    var isBlurred: Bool { get }
}

extension UIView: Blurable {}

这种设计的优势在于:

  • 不需要继承或子类化UIView
  • 所有UIView及其子类自动获得模糊能力
  • 便于维护和扩展新功能

实现流程一:图像捕获与模糊处理

模糊效果的实现首先需要将目标视图转换为图像,然后应用高斯模糊滤镜。核心代码位于FMBlurable/blurable/FMBlurable.swift文件中:

  1. 视图转图像:使用UIGraphicsBeginImageContextWithOptions捕获当前视图的视觉内容
  2. 创建模糊滤镜:通过CIFilter(name: "CIGaussianBlur")初始化高斯模糊滤镜
  3. 配置滤镜参数:设置输入图像和模糊半径(kCIInputImageKeykCIInputRadiusKey
  4. 生成模糊图像:使用CIContext将滤镜结果转换为CGImage

关键代码片段:

UIGraphicsBeginImageContextWithOptions(CGSize(width: frame.width, height: frame.height), false, 1)
layer.renderInContext(UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();

guard let blur = CIFilter(name: "CIGaussianBlur") else { return }
blur.setValue(CIImage(image: image), forKey: kCIInputImageKey)
blur.setValue(blurRadius, forKey: kCIInputRadiusKey)

实现流程二:视图替换与动画过渡

为了实现平滑的模糊切换效果,Blurable采用了视图替换策略:

  1. 创建BlurOverlay图像视图作为模糊效果的载体
  2. 使用UIView.transitionFromView实现原始视图与模糊视图的过渡动画
  3. 针对UIStackView做了特殊处理,保持视图在栈中的位置

Blurable模糊效果演示 图:Blurable实现的模糊效果对比,上方为模糊状态,下方为原始状态

实现流程三:关联对象存储状态

由于Swift扩展不能添加存储属性,Blurable使用Objective-C运行时的关联对象(Associated Objects)来存储模糊状态:

  1. 存储模糊视图:使用objc_setAssociatedObject保存模糊覆盖层

    objc_setAssociatedObject(this, &BlurableKey.blurable, blurOverlay, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
    
  2. 检查模糊状态:通过objc_getAssociatedObject判断视图是否处于模糊状态

    var isBlurred: Bool {
        return objc_getAssociatedObject(self as? UIView, &BlurableKey.blurable) is BlurOverlay
    }
    
  3. 移除关联对象:取消模糊时将关联对象设为nil

    objc_setAssociatedObject(this, &BlurableKey.blurable, nil, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
    

完整使用流程

使用Blurable为UIView添加模糊效果只需简单三步:

  1. 导入模块:确保FMBlurable.swift在项目中正确引用
  2. 调用模糊方法view.blur(blurRadius: 10)
  3. 取消模糊view.unBlur()
  4. 检查状态if view.isBlurred { ... }

结语:Swift与Objective-C的巧妙结合

Blurable项目展示了如何巧妙结合Swift的协议扩展与Objective-C运行时特性,实现既简洁又强大的功能。通过CIGaussianBlur实现核心模糊算法,用objc_setAssociatedObject解决状态存储问题,最终为iOS开发者提供了一个易用的UI模糊解决方案。

项目完整代码可通过以下命令获取:

git clone https://gitcode.com/gh_mirrors/bl/Blurable

通过分析Blurable的实现,我们不仅学习到模糊效果的技术细节,更掌握了协议扩展、关联对象等高级Swift开发技巧,这些知识可以广泛应用于其他iOS组件开发中。

【免费下载链接】Blurable Apply a Gaussian Blur to any UIView with Swift Protocol Extensions 【免费下载链接】Blurable 项目地址: https://gitcode.com/gh_mirrors/bl/Blurable

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值