如何在Swift中为UIVisualEffectView添加UILabel文字遮罩
实现文字遮罩模糊效果的Swift方案
刚好做过类似的效果!要实现「用UILabel文字作为遮罩,让UIVisualEffectView只在文字区域显示模糊」的需求,核心是利用CALayer的mask属性——只有遮罩图层中alpha值大于0的区域,才会显示原图层的内容。下面是具体的实现步骤和代码:
1. 搭建基础UI结构
首先在ViewController里创建好UIImageView(背景图)、UIVisualEffectView(模糊层)和UILabel(文字遮罩源),先把布局搞定:
import UIKit class ViewController: UIViewController { // 把视图设为类属性,方便后续布局更新时调整遮罩 private let imageView = UIImageView() private let blurView = UIVisualEffectView(effect: UIBlurEffect(style: .systemMaterialDark)) private let titleLabel = UILabel() override func viewDidLoad() { super.viewDidLoad() setupBaseUI() setupTextMask() } private func setupBaseUI() { // 背景图片视图 imageView.image = UIImage(named: "your-background-image") // 替换成你的图片名 imageView.contentMode = .scaleAspectFill imageView.clipsToBounds = true view.addSubview(imageView) // 模糊视图 view.addSubview(blurView) // 文字标签 titleLabel.text = "BLURRED TEXT" titleLabel.font = UIFont.systemFont(ofSize: 72, weight: .black) titleLabel.textColor = .white // 这个颜色只是调试用,遮罩只看alpha通道 view.addSubview(titleLabel) // 用AutoLayout布局(如果用frame的话直接设置frame即可) imageView.translatesAutoresizingMaskIntoConstraints = false blurView.translatesAutoresizingMaskIntoConstraints = false titleLabel.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor), imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor), imageView.topAnchor.constraint(equalTo: view.topAnchor), imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor), blurView.leadingAnchor.constraint(equalTo: view.leadingAnchor), blurView.trailingAnchor.constraint(equalTo: view.trailingAnchor), blurView.topAnchor.constraint(equalTo: view.topAnchor), blurView.bottomAnchor.constraint(equalTo: view.bottomAnchor), titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor), titleLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor) ]) } }
2. 核心:设置文字遮罩
接下来实现遮罩的核心逻辑,把Label的文字转换成路径图层,作为模糊视图的遮罩:
extension ViewController { private func setupTextMask() { guard let text = titleLabel.text, let font = titleLabel.font else { return } // 创建承载文字路径的形状图层 let textMaskLayer = CAShapeLayer() // 生成文字的贝塞尔路径 let textPath = UIBezierPath( text: text, withAttributes: [NSAttributedString.Key.font: font] ) // 调整路径位置,和Label在模糊视图上的位置对齐 let labelFrameInBlurView = blurView.convert(titleLabel.frame, from: titleLabel.superview) textPath.apply(CGAffineTransform(translationX: labelFrameInBlurView.origin.x, y: labelFrameInBlurView.origin.y)) // 配置形状图层 textMaskLayer.path = textPath.cgPath textMaskLayer.fillRule = .nonZero // 普通文字用这个,镂空文字用.evenOdd // 将形状图层设为模糊视图的遮罩 blurView.layer.mask = textMaskLayer } // 如果用AutoLayout,需要在布局更新后重新调整遮罩 override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() setupTextMask() } }
3. 关键注意事项
- 遮罩原理:遮罩图层的alpha通道决定了原图层的显示区域——alpha>0的地方显示模糊,alpha=0的地方透出下方的清晰背景图。
- 布局适配:如果使用AutoLayout,一定要在
viewDidLayoutSubviews里重新调用遮罩设置方法,因为AutoLayout会在这个阶段确定最终的视图frame。 - 模糊风格调整:可以修改
UIBlurEffect.Style的参数,比如.systemMaterial、.light、.dark等,适配你的背景和文字风格。 - 复杂文字样式:如果需要带描边、阴影的文字作为遮罩,可以先把Label渲染成UIImage,再用
UIImageView.layer作为遮罩,不过路径方案已经能满足大部分常规需求。
内容的提问来源于stack exchange,提问作者Jacob Cavin
相关产品推荐
相关产品推荐

