SwiftUI中为文本实现液态玻璃(Liquid Glass)效果的技术求助
SwiftUI中为文本实现液态玻璃(Liquid Glass)效果的技术求助
嗨,我之前也卡过这个问题!确实SwiftUI的glassEffect直接套在Text上会有点水土不服——它本来是给容器类视图(比如Rectangle、RoundedRectangle)设计的,没法直接识别Text的文字路径。不过有几个很实用的方案,我给你拆解一下:
方案一:基础玻璃文本效果(最直接)
核心思路是先做一个带玻璃效果的容器,再用文本把容器“挖”出文字的形状,这样玻璃效果就只显示在文字区域里。代码示例:
struct BasicLiquidGlassText: View { var body: some View { // 1. 先创建一个和文本尺寸匹配的容器 Rectangle() .fill(.clear) // 透明填充,让玻璃效果能采样背景 .glassEffect( in: .rect(cornerRadius: 4), // 可以调整圆角适配文字风格 style: .regular // 可选thin/regular/thick,控制模糊程度 ) .frame(width: 320, height: 60) // 尺寸尽量贴合文本大小 // 2. 用文本作为遮罩,只保留文字形状的玻璃效果 .mask( Text("Liquid Glass") .font(.system(size: 30, weight: .bold)) .multilineTextAlignment(.center) ) } }
小技巧:
- 如果想让玻璃效果更贴合文字的边角,可以把
in: .rect(cornerRadius: 4)换成in: .roundedRect(cornerRadius: 2),或者自定义路径 - 一定要确保容器的
frame和文本尺寸匹配,不然会出现多余的玻璃区域
方案二:带动态效果的“液态”玻璃文本
如果想要更有“液态”的感觉(比如微微晃动、扭曲),可以在基础上叠加动画和扭曲效果,模拟液体流动的质感:
struct AnimatedLiquidGlassText: View { // 用状态变量控制偏移动画 @State private var shakeOffset = CGSize.zero var body: some View { // 先做一个带渐变的文本作为底层 Text("Liquid Glass") .font(.system(size: 30, weight: .bold)) .multilineTextAlignment(.center) .foregroundStyle( LinearGradient( colors: [.blue, .mint, .green], startPoint: .leading, endPoint: .trailing ) ) // 叠加玻璃效果层 .overlay { Rectangle() .glassEffect(style: .thin) .distortionEffect( // 简单的扭曲Shader,模拟液态变形 ShaderLibrary.default.distortion(.float(shakeOffset.width / 80)), maxSampleOffset: CGSize(width: 10, height: 10) ) .mask( Text("Liquid Glass") .font(.system(size: 30, weight: .bold)) ) } // 启动晃动动画 .offset(shakeOffset) .onAppear { withAnimation( Animation.easeInOut(duration: 1.8) .repeatForever(autoreverses: true) ) { shakeOffset = CGSize(width: 6, height: -4) } } } }
注意点:
distortionEffect需要SwiftUI 4.0+(iOS 16+)支持,如果要兼容更低版本,可以去掉这部分,只保留晃动动画- 玻璃效果的清晰度和背景有关,如果背景是纯色,玻璃效果会比较淡;如果背景有图片或复杂色彩,效果会更明显
额外优化建议
- 给文本加个轻微阴影,让玻璃文本更有层次感:在
mask里的Text后面加上.shadow(color: .black.opacity(0.2), radius: 2, x: 1, y: 1) - 可以调整
glassEffect的style参数,.thick会更模糊,.thin更通透,根据你的设计需求选 - 如果想让文字的玻璃效果有颜色 tint,可以在容器的
fill里加个半透明颜色,比如.fill(.blue.opacity(0.1)),再叠加玻璃效果
其实本质上就是绕个弯——把玻璃效果从容器“转移”到文本形状上,你可以根据自己的需求调整细节,试试上面的代码,应该能得到你想要的液态玻璃文本效果!




