SwiftUI 中的模糊效果详解:.blur、.material、UIVisualEffectView

模糊效果(Blur Effect)是 iOS 用户界面设计的重要组成部分,它被广泛应用于系统控制中心、通知背景、弹窗蒙版等场景,营造出“毛玻璃”的视觉层次感。
本文将深入解析 SwiftUI 中实现模糊效果的三种主流方式:.blur(radius:).background(Material)、以及封装 UIKit 的 UIVisualEffectView,并详细说明每种方式的适用场景、性能表现及实现方式。


一、使用 .blur(radius:) 修饰符添加模糊

基础用法

Image("photo").resizable().scaledToFill().blur(radius: 10)

在这里插入图片描述

API 说明

  • 函数名.blur(radius:opaque:)
  • 参数
    • radius: CGFloat:模糊的半径,数值越大,模糊越强;
    • opaque: Bool = false(可选):
      • 设置为 true 会提升性能,但会关闭透明效果;
      • 设置为 false 可以保留透明度,适用于图像叠加。

示例:模糊前景图像

ZStack {Image("background").resizable().scaledToFill()Image("logo").resizable().frame(width: 100, height: 100).blur(radius: 8)
}

✅ 适合前景局部模糊,⚠️ 不具备“磨砂玻璃”风格的半透明模糊。
在这里插入图片描述


二、使用系统材料 Material 实现半透明磨砂效果

从 iOS 15 起,Apple 为 SwiftUI 引入了 视觉材料 API(Material API),用于模拟 iOS 系统的磨砂玻璃风格(例如通知中心、弹窗等)。

基础用法

Text("Hello, SwiftUI").padding().background(.ultraThinMaterial).cornerRadius(12)

API 说明

    @inlinable nonisolated public func background<S>(_ style: S, ignoresSafeAreaEdges edges: Edge.Set = .all) -> some View where S : ShapeStyle
Material 类型
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 10.0, *)
extension ShapeStyle where Self == Material {/// A material that's somewhat translucent.public static var regularMaterial: Material { get }/// A material that's more opaque than translucent.public static var thickMaterial: Material { get }/// A material that's more translucent than opaque.public static var thinMaterial: Material { get }/// A mostly translucent material.public static var ultraThinMaterial: Material { get }/// A mostly opaque material.public static var ultraThickMaterial: Material { get }
}
  • .ultraThinMaterial:最透明的视觉效果;
  • .thinMaterial:比 ultraThin 稍微厚一点;
  • .regularMaterial:中等模糊;
  • .thickMaterial:模糊感更强;
  • .ultraThickMaterial:非常明显的模糊层。

在这里插入图片描述

示例:毛玻璃背景卡片

ZStack {Image("background").resizable().scaledToFill().ignoresSafeArea()VStack {Text("This is a glass card").font(.headline).foregroundColor(.white).padding().background(.ultraThinMaterial).cornerRadius(16)}
}

在这里插入图片描述

优势

  • 系统原生优化;
  • 自动根据暗黑/亮色模式适配背景;
  • 可叠加阴影、边框等样式。

三、封装 UIKit 的 UIVisualEffectView 用于自定义模糊风格

在 SwiftUI 中,若需要更细致的控制,比如使用 .dark.extraLight 等传统 UIKit 风格的模糊效果,可通过 UIViewRepresentable 封装 UIKit 的 UIVisualEffectView

Step 1:创建封装视图组件

struct VisualEffectBlur: UIViewRepresentable {var blurStyle: UIBlurEffect.Stylefunc makeUIView(context: Context) -> UIVisualEffectView {return UIVisualEffectView(effect: UIBlurEffect(style: blurStyle))}func updateUIView(_ uiView: UIVisualEffectView, context: Context) {uiView.effect = UIBlurEffect(style: blurStyle)}
}

UIBlurEffect.Style 枚举(UIKit)

extension UIBlurEffect {@available(iOS 8.0, *)public enum Style : Int, @unchecked Sendable {/// 非常浅的白色模糊(适合深色背景)case extraLight = 0/// 淡白色模糊,透明度适中(适合中性色背景)case light = 1/// 深色模糊,带有黑色背景(适合浅色背景或亮色 UI)case dark = 2/// 常规模糊效果,视觉强度适中,适用于大部分场景@available(iOS 10.0, *)case regular = 4/// 强烈的模糊效果,比 regular 更加明显@available(iOS 10.0, *)case prominent = 5// MARK: - 以下为基于系统材质的模糊效果,自动适配明/暗模式/// 极薄系统材料风格,模糊度最轻(自适应明暗模式)@available(iOS 13.0, *)case systemUltraThinMaterial = 6/// 较薄系统材料风格(比 ultraThin 稍强)@available(iOS 13.0, *)case systemThinMaterial = 7/// 常规厚度系统材料,适用于大多数模糊背景@available(iOS 13.0, *)case systemMaterial = 8/// 较厚系统材料模糊,遮挡性更强@available(iOS 13.0, *)case systemThickMaterial = 9/// 特别为 toolbar、tabbar 等 chrome UI 元素设计的材料模糊@available(iOS 13.0, *)case systemChromeMaterial = 10// MARK: - 以下为固定亮色风格的材料模糊(不会根据暗色模式变换)/// 极薄亮色材料@available(iOS 13.0, *)case systemUltraThinMaterialLight = 11/// 较薄亮色材料@available(iOS 13.0, *)case systemThinMaterialLight = 12/// 常规亮色材料@available(iOS 13.0, *)case systemMaterialLight = 13/// 厚重亮色材料@available(iOS 13.0, *)case systemThickMaterialLight = 14/// 用于亮色 UI chrome 元素的材料@available(iOS 13.0, *)case systemChromeMaterialLight = 15// MARK: - 以下为固定暗色风格的材料模糊(不会根据亮色模式变换)/// 极薄暗色材料@available(iOS 13.0, *)case systemUltraThinMaterialDark = 16/// 较薄暗色材料@available(iOS 13.0, *)case systemThinMaterialDark = 17/// 常规暗色材料@available(iOS 13.0, *)case systemMaterialDark = 18/// 厚重暗色材料@available(iOS 13.0, *)case systemThickMaterialDark = 19/// 用于暗色 UI chrome 元素的材料@available(iOS 13.0, *)case systemChromeMaterialDark = 20}
}

Step 2:在 SwiftUI 中使用

  // 枚举所有 UIBlurEffect.Style(仅支持当前系统版本的)let blurStyles: [(name: String, style: UIBlurEffect.Style)] = [("extraLight", .extraLight),("light", .light),("dark", .dark),("regular", .regular),("prominent", .prominent),("systemUltraThinMaterial", .systemUltraThinMaterial),("systemThinMaterial", .systemThinMaterial),("systemMaterial", .systemMaterial),("systemThickMaterial", .systemThickMaterial),("systemChromeMaterial", .systemChromeMaterial),("systemUltraThinMaterialLight", .systemUltraThinMaterialLight),("systemThinMaterialLight", .systemThinMaterialLight),("systemMaterialLight", .systemMaterialLight),("systemThickMaterialLight", .systemThickMaterialLight),("systemChromeMaterialLight", .systemChromeMaterialLight),("systemUltraThinMaterialDark", .systemUltraThinMaterialDark),("systemThinMaterialDark", .systemThinMaterialDark),("systemMaterialDark", .systemMaterialDark),("systemThickMaterialDark", .systemThickMaterialDark),("systemChromeMaterialDark", .systemChromeMaterialDark),]var body: some View {ScrollView {VStack(spacing: 0) {ForEach(blurStyles, id: \.name) { item inZStack {Image("background").resizable().scaledToFill().frame(height: 150).clipped()VisualEffectBlur(blurStyle: item.style).frame(height: 150)Text(item.name).font(.title3).bold().foregroundColor(.white).shadow(radius: 2)}.frame(maxWidth: .infinity)}}}}
}

在这里插入图片描述

实战技巧:只模糊部分区域

示例:只模糊圆形区域

ZStack {Image("background").resizable().scaledToFill()Circle().fill(.thinMaterial).frame(width: 180, height: 180)
}

示例:自定义模糊背景加遮罩

VisualEffectBlur(blurStyle: .light).mask(RoundedRectangle(cornerRadius: 20).frame(width: 300, height: 200))

性能注意事项

技术系统要求性能表现使用建议
.blur(radius:)iOS 13+渲染开销较高少量、静态使用
.background(.material)iOS 15+系统优化推荐优先使用
UIVisualEffectView 封装iOS 13+原生高效可用于旧版本

建议避免在 滚动视图或动画 中频繁使用大半径的 .blur(radius:),可以改用 Material 实现近似视觉风格但更高性能。


附加内容:模糊叠加 + 动画

struct AnimatedBlurView: View {@State private var blurAmount: CGFloat = 0var body: some View {VStack {Image("background").resizable().scaledToFill().frame(height: 300).blur(radius: blurAmount)Text("blur value: \(blurAmount)")Slider(value: $blurAmount, in: 0...20).padding()}}
}

请添加图片描述


总结

模糊方式系统支持适用场景控制精度
.blur(radius:)iOS 13+简单模糊、图片处理高(可动画)
.background(.material)iOS 15+毛玻璃视觉、系统一致性
UIVisualEffectViewiOS 13+自定义模糊、旧系统支持

SwiftUI 通过系统级 API 与 UIKit 封装的配合,已能满足多数现代 iOS UI 设计中关于模糊效果的需求。选择合适的模糊方式,不仅能提升用户体验,还能确保性能表现优良。


最后,希望能够帮助到有需要的朋友,如果觉得有帮助,还望点个赞,添加个关注,笔者也会不断地努力,写出更多更好用的文章。

📚 推荐阅读

  • Apple Developer - Material
  • WWDC2021: Explore visual effects in SwiftUI
  • UIVisualEffectView | Apple Documentation

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/912990.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/912990.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Euler2203安装.NetCore6.0环境操作步骤

# 1. 下载.NET二进制包 wget https://download.visualstudio.microsoft.com/download/pr/xxxx/dotnet-sdk-6.0.xxx-linux-x64.tar.gz把dotnet-sdk-6.0.428-linux-x64.tar.gz放到一个目录里面# 2. 创建安装目录sudo mkdir -p /usr/share/dotnetsudo tar -zxf dotnet-sdk-6.0.428…

解决安装SunloginClient问题记录(Ubuntu 24.04.2)

成功安装流程&#xff08;Ubuntu 24.04.2&#xff09; 1. 首次尝试安装&#xff08;失败&#xff0c;缺少依赖&#xff09; sudo dpkg -i ./SunloginClient_15.2.0.63064_amd64.deb sudo apt-get install -f # 修复依赖&#xff08;此时提示缺少 libgconf-2-4&#xff09; …

wordpress安装教程

一、安装软件 1、apache sudo apt install apache2 -y 2、mysql sudo apt install mysql-server -y 3、PHP及其扩展 sudo apt install php libapache2-mod-php php-mysql php-curl php-gd php-mbstring php-xml php-xmlrpc php-soap php-intl php-zip php-fpm -y 重启ap…

C#,VB.NET从JSON数据里提取数组中的对象节点值

在VB.NET中&#xff0c;若要从 JSON 数据里提取Data.DataList数组中的CategoryId&#xff0c;并将其转换为VB.NET数组&#xff0c;可借助Json.NET&#xff08;Newtonsoft.Json&#xff09;库来实现。下面为你详细介绍具体的实现步骤和代码示例&#xff1a; 一、实现 JSON 到数…

Flutter 进阶:实现带圆角的 CircularProgressIndicator

在 Flutter 中&#xff0c;我们经常使用 CircularProgressIndicator 来展示加载进度。但是你是否注意到&#xff1a;它的进度端始终是“平头”的&#xff08;直角&#xff09;&#xff1f; 这在一些 UI 设计中并不美观&#xff0c;特别是想实现类似 Apple 健身环那样“前端圆清…

解决CentOS7下载docker-compose出现没有可用软件包问题

1 问题描述 今天在使用虚拟机CentOS 7系统安装docker-compose时&#xff0c;用的是aliyun镜像&#xff0c;出现没有可用软件包的问题&#xff0c;这就说明不是因为网络&#xff0c;而是因为aliyun镜像没有该软件包。 2 解决办法 这里推荐最稳定的解决办法&#xff0c;去docker-…

基于SpringBoot+Vue的酒类仓储管理系统

文档包含用例图、系统架构图、系统功能结构图、实体属性图、总体e-r图。一.系统开发工具与环境搭建1.系统设计开发工具后端使用Java编程语言的Spring boot框架项目架构&#xff1a;B/S架构运行环境&#xff1a;win10/win11、jdk17前端&#xff1a;技术&#xff1a;框架Vue.js&a…

月付物理服务器租用平台-青蛙云

青蛙云物理服务器租用服务概述 青蛙云是一家提供物理服务器租用服务的平台&#xff0c;支持月付、年付等灵活付费方式&#xff0c;物理服务器适合企业或个人用户的高性能计算需求。其服务覆盖多地区机房&#xff0c;提供多种配置选项&#xff0c;支持定制化需求。 核心优势 …

基于二分类方法和安全系数方法使用comsol with matlab蒙特卡洛模拟实现边坡失效概率计算——随机变量模型

基于二分类方法和安全系数方法使用comsol with matlab蒙特卡洛模拟实现边坡失效概率计算——随机变量模型 模型和全部代码下载随机变量模拟加载comsol模型蒙特卡洛模拟(分类模型)蒙特卡洛模拟(安全系数模型)内聚力和内摩擦角随机变量分布二分类稳定性1000次运行结果失效概率…

机器学习-02(深度学习的基本概念)

机器学习的步骤 1.定义带有未知参数的函数 线性模型&#xff08;linear models&#xff09;具有较大的限制&#xff08;Model Bias&#xff09; y b wx 无论如何更改b或者w&#xff0c;其只会呈现出一条直线&#xff0c;不能满足更加复杂的现实情况。 我们可以将复杂的函…

InspireFace C++ 架构分析

InspireFace C 架构分析 https://github.com/deepinsight/insightface/tree/master/cpp-package/inspireface 1. 项目概述 InspireFace 是一个高性能的人脸识别和分析 SDK&#xff0c;采用 C 开发&#xff0c;提供了完整的人脸检测、跟踪、特征提取、活体检测、属性分析等功…

【网络安全】Webshell命令执行失败解决思路

前言费尽心思上传了webshell&#xff0c;上传下载都没问题&#xff0c;却发现命令执行总是失败&#xff1f;最近也打点也遇到了这些问题&#xff0c;网上有部分文章&#xff0c;但都是零碎知识点并且实战不一定能用&#xff0c;今天就结合我个人经验剖析webshell上线后cmd命令执…

【机器人】复现 HOV-SG 机器人导航 | 分层 开放词汇 | 3D 场景图

HOV-SG 是通过语言指令实现机器人导航的&#xff0c;核心特点是分层结构、开放词汇、3D场景图。 来自RSS 2024&#xff0c;大规模、多层次的环境构建精确的、开放词汇的3 场景图&#xff0c;并使机器人能够通过语言指令在其中有效地导航。 论文地址&#xff1a;Hierarchical …

jvm 锁升级机制

Java 虚拟机&#xff08;JVM&#xff09;中的锁升级机制&#xff08;也称为锁膨胀&#xff09;是 HotSpot 虚拟机为了优化 synchronized 关键字的性能而引入的一项重要技术。它的核心思想是&#xff1a;根据实际遇到的竞争激烈程度&#xff0c;动态地将锁从开销最小的状态逐步升…

金蝶云星空 (9.0版本) ERP的WebApi接口随机出现SSLException

环境&#xff1a; java-1.8.0-openjdk-1.8.0.131 hutool-all 依赖&#xff0c; 5.8.25版本 项目背景&#xff1a; 发版上线&#xff0c;用的hutool工具类 HttpUtil.createPost() &#xff0c;请求域名为https://xxx.ik3cloud.com/k3cloud 的金蝶ERP webapi接口 问题&#xff1…

用java,把12.25.pdf从最后一个点分割,得到pdf

要在Java中从文件名 12.25.pdf 的最后一个点&#xff08;.&#xff09;分割文件名和扩展名&#xff0c;可以使用 String 类的 lastIndexOf() 和 substring() 方法。以下是一个示例代码&#xff1a; public class FileNameSplitter {public static void main(String[] args) {St…

UE5 重新编译插件版本

打开要转换的UE的安装目录&#xff0c;一直找到这个文件 不要双击&#xff0c;在地址栏里输入cmd打开命令行&#xff0c;输入如下指令 RunUAT.bat BuildPlugin -plugin"E:\OldPlugin\chatbot5.3\chatbot\chatbot.uplugin" -package"E:\NewPlugin"-plugin…

Linux下的调试器-gdb(16)

文章目录 预备知识&#xff08;9-2.30.00&#xff09;快速认识 gdbgdb 的命令1. 更换成 cgdb2. 打和去除断点3. 逐语句与逐过程4. 使能&#xff08;激活&#xff09;断点 调试思想1. 找到问题&#xff08;找到问题所在的区域&#xff09;2. 查看代码的上下文 补充调试技巧1. wa…

李宏毅NLP-7-计算分数和训练和测试

文章目录 分数计算训练测试 分数计算 插入式序列生成模型的概率计算逻辑&#xff0c;核心是将 “生成序列 h 的过程” 拆解为一系列插入操作&#xff0c;并通过步骤概率的乘积计算总概率 P ( h ∣ X ) P(h∣X) P(h∣X)。以下从 模型框架、步骤分解、概率计算 三个层面解析&…

Python字符与ASCII转换方法

在Python中&#xff0c;可以使用内置函数 ord() 和 chr() 来转换字符和ASCII码&#xff1a; ​获取字符的ASCII码​ - 用 ord() ascii_code ord(A) # 返回 65 ​将ASCII码转为字符​ - 用 chr() character chr(65) # 返回 A 示例&#xff1a; # 打印字母A-Z的ASCII码…