SwiftUI 开发之旅:毛玻璃效果的设计理念和实现

6,191 阅读4分钟

毛玻璃,学名「类玻璃柔光材质」,在设计中也叫「玻璃拟态」(Glass morphism)。在生活中叫磨砂玻璃,俗称“毛玻璃”。

懂点设计

毛玻璃效果最早出应用在 2007 年微软的 Windows Vista 和 win7 的系统 UI 中。

image.png

win7 毛玻璃效果

之后,苹果分别在 2013 年发布的 ios7 系统和 2014 年发布的 OS X 10.10 Yosemite 系统中广泛使用了这个效果,比如底部菜单栏,通知中心等。透明的效果再结合当下流行的扁平化设计,这些变化让大家觉得耳目一新。

image.png

ios7 毛玻璃效果

image.png

MacOS 10.10 毛玻璃效果

在之后的很长时间里,这种风格成为了设计师们常用的手法。直到在近期发布的 Win11 以及 MacOS Big Sur 中更加强化了毛玻璃质感,又将玻璃拟态风格的趋势掀起了一个小高潮。

image.png image.png

各家对于毛玻璃的实现有些许差异,但关于毛玻璃效果,主要有 4 个特征:

  • 透明感:使用背景模糊和高斯模糊的磨砂效果,呈现出通透感。
  • 层次感: 通过前后关系的叠加,拉开界面元素层次,突出重点。
  • 色彩感: 强调模糊透明度的鲜明,鲜艳的背景底色,使用鲜艳色彩作为强调色并且从半透明层中透出,更突出了模糊的透明效果。
  • 玻璃质感: 通过边缘的微妙处理,于半透明物体上的细微且光亮的边框,表现出玻璃质感。

毛玻璃的应用场景

毛玻璃在设计中经常出现,常用的一些设计场景包括以下内容。

  • 图标设计

image.pngimage.png

  • 彩色背景
image.png
  • 卡片式
image.png

SwiftUI 毛玻璃

SwiftUI 在 iOS15 上提供了名为 Material 的背景模糊效果,适合应用于背景图片上的文字说明,叠加背景模糊的色块以凸显文字。

image.png

上图的效果使用 ultraThinMaterial 以最轻微模糊的选项,此时能看到背景的模糊效果。

Material 提供了5个模糊参数,由弱到强分别为:

  • ultraThinMaterial
  • thinMaterial
  • regularMaterial
  • thickMaterial
  • ultraThickMaterial

SwiftUI 毛玻璃效果的实现

通过 Material 的 API 可以实现毛玻璃的 UI 效果,以下示例是简单的通过 SwiftUI 代码实现的毛玻璃步骤:

  1. 使用 ZStack 设置一个背景色。
  2. 再给块的背景设置 Material。
struct Test4: View {
    var body: some View {
        ZStack {
            Color.init(hex: "31D3D3").edgesIgnoringSafeArea(.all)
            VStack {
               Text(".ultraThin")
                    .padding()
                    .frame(width: 200, height: 100)
                    .background(.ultraThinMaterial)
                Text(".thin")
                     .padding()
                     .frame(width: 200, height: 100)
                     .background(.thinMaterial)
                Text(".regular")
                     .padding()
                     .frame(width: 200, height: 100)
                     .background(.regularMaterial)
                Text(".thick")
                     .padding()
                     .frame(width: 200, height: 100)
                     .background(.thickMaterial)
                Text(".ultraThick")
                     .padding()
                     .frame(width: 200, height: 100)
                     .background(.ultraThickMaterial)
            }
            .padding()
            .shadow(color: .black.opacity(0.25), radius: 5, x: 0, y: 8)
       }

   }

}

下面效果展现了 5 种强度在深色模式和浅色模式下的显示效果,可以明显看出到在 thickMaterial 以上程度的背景模糊效果过强以至于难以看到背景色块。

image.pngimage.png

在 swiftui 中,毛玻璃效果很适合用来展示卡片,或者是弹窗,sheet等内容的背景展示,下面来看一个在 sheet 中使用的例子。

我们在上个示例的基础上填写一些内容和 sheet 相关代码:

import SwiftUI

struct Test4: View {

    @State var show: Bool = **false**
    @State var value1 = ""
    
    var body: some View {
        ZStack {
            // ...
        }
        .sheet(isPresented: $show) {
            ZStack {
                Rectangle()
                    .fill(.thickMaterial) // 毛玻璃效果
                VStack {
                    HStack {
                        Button(action: {
                            self.show = false
                        }) {
                            Image(systemName: "xmark")
                        }
                        Spacer(minLength: 0)
                        Text("文章").bold()
                        Spacer(minLength: 0)
                    }.padding()
                    VStack {
                        Text("SwiftUI 开发之旅").padding()
                        Text("毛玻璃效果的设计理念和实现").padding()
                    }
                    Spacer()
                    HStack {
                        Button(action: {
                            self.show = false
                        }, label: {
                            Text("点赞")
                                .padding(.horizontal, 2)
                                .padding(.vertical, 15)
                                .frame(maxWidth: .infinity)
                                .background(Color.blue)
                                .foregroundColor(.white).cornerRadius(12)
                        })
                        .padding(.bottom)
                    }.padding()
                }.padding()
            }
        }
    }
}

image.png

然鹅,并没有出现我们想要的毛玻璃效果。这是因为 sheet 模态框默认情况下背景是不透明的,我们还需要将模态框的背景色设置为透明,才能正常显示毛玻璃的效果。

新增一个 BackgroundClearView 结构体,来实现背景清除功能

struct BackgroundClearView: UIViewRepresentable {
    func makeUIView(context: Context) -> UIView {
        let view = UIView()
        DispatchQueue.main.async {
            view.superview?.superview?.backgroundColor = .clear
        }
        return view
    }

    func updateUIView(_ uiView: UIView, context: Context) {}
}

然后给 ZStack 添加 background 修饰符:

.sheet(isPresented: $show) {
      ZStack {
       // ...
      }
      .background(BackgroundClearView())
}

image.png

此时模态框底部有一些留白,再给 ZStack 添加一个 ignoresSafeArea 修饰符处理一下安全区域就可以了。

来看看最终效果。

屏幕录制2022-11-01 17.gif

总结

我们回顾了毛玻璃效果的诞生和它的实际应用。学习了如何在 swiftui 中应用毛玻璃效果,可以看得出,在有大面积色块的背景上运用毛玻璃效果能带来不一样的用户体验,比如 sheet,消息卡片等。不妨的在你的应用中运用这一设计,给你的用户体验添加一些不一样的东西吧。

这是 SwiftUI 开发之旅专栏的文章,是 swiftui 开发学习的经验总结及实用技巧分享,欢迎关注该专栏,会坚持输出。同时欢迎关注我的个人公众号 @JSHub:提供最新的开发信息速报,优质的技术干货推荐。或是查看我的个人博客:Devcursor

👍点赞:如果有收获和帮助,请点个赞支持一下!

🌟收藏:欢迎收藏文章,随时查看!

💬评论:欢迎评论交流学习,共同进步!