liquid-glass-design

liquid-glass-design

热门

iOS 26 液态玻璃设计系统——为 SwiftUI、UIKit 和 WidgetKit 提供具有模糊、反射和交互变形能力的动态玻璃材质。

23万Star
3.5万Fork
更新于 2026/7/14
SKILL.md
readonly只读
name
liquid-glass-design
description

iOS 26 液态玻璃设计系统——为 SwiftUI、UIKit 和 WidgetKit 提供具有模糊、反射和交互变形能力的动态玻璃材质。

液态玻璃设计系统 (iOS 26)

实现 Apple 液态玻璃(Liquid Glass)的模式——一种动态材质,能够模糊其背后的内容,反射周围内容的颜色和光线,并对触摸和指针交互做出反应。涵盖 SwiftUI、UIKit 和 WidgetKit 集成。

何时使用

  • 为 iOS 26+ 构建或更新应用,采用新的设计语言
  • 实现玻璃风格的按钮、卡片、工具栏或容器
  • 创建玻璃元素之间的变形过渡
  • 为小组件应用液态玻璃效果
  • 将现有的模糊/材质效果迁移到新的液态玻璃 API

核心模式 — SwiftUI

基本玻璃效果

为任意视图添加液态玻璃的最简单方式:

Text("Hello, World!")
    .font(.title)
    .padding()
    .glassEffect()  // 默认:常规变体,胶囊形状

自定义形状和色调

Text("Hello, World!")
    .font(.title)
    .padding()
    .glassEffect(.regular.tint(.orange).interactive(), in: .rect(cornerRadius: 16.0))

关键自定义选项:

  • .regular — 标准玻璃效果
  • .tint(Color) — 添加颜色色调以突出显示
  • .interactive() — 对触摸和指针交互做出反应
  • 形状:.capsule(默认)、.rect(cornerRadius:).circle

玻璃按钮样式

Button("Click Me") { /* 操作 */ }
    .buttonStyle(.glass)

Button("Important") { /* 操作 */ }
    .buttonStyle(.glassProminent)

用于多个元素的 GlassEffectContainer

始终将多个玻璃视图包裹在容器中,以获得性能和变形效果:

GlassEffectContainer(spacing: 40.0) {
    HStack(spacing: 40.0) {
        Image(systemName: "scribble.variable")
            .frame(width: 80.0, height: 80.0)
            .font(.system(size: 36))
            .glassEffect()

        Image(systemName: "eraser.fill")
            .frame(width: 80.0, height: 80.0)
            .font(.system(size: 36))
            .glassEffect()
    }
}

spacing 参数控制合并距离——距离越近的元素,其玻璃形状融合得越紧密。

合并玻璃效果

使用 glassEffectUnion 将多个视图合并为单个玻璃形状:

@Namespace private var namespace

GlassEffectContainer(spacing: 20.0) {
    HStack(spacing: 20.0) {
        ForEach(symbolSet.indices, id: \.self) { item in
            Image(systemName: symbolSet[item])
                .frame(width: 80.0, height: 80.0)
                .glassEffect()
                .glassEffectUnion(id: item < 2 ? "group1" : "group2", namespace: namespace)
        }
    }
}

变形过渡

在玻璃元素出现/消失时创建平滑变形:

@State private var isExpanded = false
@Namespace private var namespace

GlassEffectContainer(spacing: 40.0) {
    HStack(spacing: 40.0) {
        Image(systemName: "scribble.variable")
            .frame(width: 80.0, height: 80.0)
            .glassEffect()
            .glassEffectID("pencil", in: namespace)

        if isExpanded {
            Image(systemName: "eraser.fill")
                .frame(width: 80.0, height: 80.0)
                .glassEffect()
                .glassEffectID("eraser", in: namespace)
        }
    }
}

Button("Toggle") {
    withAnimation { isExpanded.toggle() }
}
.buttonStyle(.glass)

扩展水平滚动到侧边栏下方

要允许水平滚动内容延伸到侧边栏或检查器下方,请确保 ScrollView 内容到达容器的前缘/后缘。当布局延伸到边缘时,系统会自动处理侧边栏下方的滚动行为——无需额外修饰符。

核心模式 — UIKit

基本 UIGlassEffect

let glassEffect = UIGlassEffect()
glassEffect.tintColor = UIColor.systemBlue.withAlphaComponent(0.3)
glassEffect.isInteractive = true

let visualEffectView = UIVisualEffectView(effect: glassEffect)
visualEffectView.translatesAutoresizingMaskIntoConstraints = false
visualEffectView.layer.cornerRadius = 20
visualEffectView.clipsToBounds = true

view.addSubview(visualEffectView)
NSLayoutConstraint.activate([
    visualEffectView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
    visualEffectView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
    visualEffectView.widthAnchor.constraint(equalToConstant: 200),
    visualEffectView.heightAnchor.constraint(equalToConstant: 120)
])

// 向 contentView 添加内容
let label = UILabel()
label.text = "Liquid Glass"
label.translatesAutoresizingMaskIntoConstraints = false
visualEffectView.contentView.addSubview(label)
NSLayoutConstraint.activate([
    label.centerXAnchor.constraint(equalTo: visualEffectView.contentView.centerXAnchor),
    label.centerYAnchor.constraint(equalTo: visualEffectView.contentView.centerYAnchor)
])

用于多个元素的 UIGlassContainerEffect

let containerEffect = UIGlassContainerEffect()
containerEffect.spacing = 40.0

let containerView = UIVisualEffectView(effect: containerEffect)

let firstGlass = UIVisualEffectView(effect: UIGlassEffect())
let secondGlass = UIVisualEffectView(effect: UIGlassEffect())

containerView.contentView.addSubview(firstGlass)
containerView.contentView.addSubview(secondGlass)

滚动边缘效果

scrollView.topEdgeEffect.style = .automatic
scrollView.bottomEdgeEffect.style = .hard
scrollView.leftEdgeEffect.isHidden = true

工具栏玻璃集成

let favoriteButton = UIBarButtonItem(image: UIImage(systemName: "heart"), style: .plain, target: self, action: #selector(favoriteAction))
favoriteButton.hidesSharedBackground = true  // 选择退出共享玻璃背景

核心模式 — WidgetKit

渲染模式检测

struct MyWidgetView: View {
    @Environment(\.widgetRenderingMode) var renderingMode

    var body: some View {
        if renderingMode == .accented {
            // 色调模式:白色色调,主题玻璃背景
        } else {
            // 全彩模式:标准外观
        }
    }
}

用于视觉层次的强调组

HStack {
    VStack(alignment: .leading) {
        Text("Title")
            .widgetAccentable()  // 强调组
        Text("Subtitle")
            // 主要组(默认)
    }
    Image(systemName: "star.fill")
        .widgetAccentable()  // 强调组
}

色调模式下的图像渲染

Image("myImage")
    .widgetAccentedRenderingMode(.monochrome)

容器背景

VStack { /* 内容 */ }
    .containerBackground(for: .widget) {
        Color.blue.opacity(0.2)
    }

关键设计决策

决策 理由
GlassEffectContainer 包裹 性能优化,支持玻璃元素之间的变形
spacing 参数 控制合并距离——微调元素需要多近才能融合
@Namespace + glassEffectID 在视图层次结构变化时实现平滑变形过渡
interactive() 修饰符 显式选择触摸/指针反应——并非所有玻璃都需要响应
UIKit 中的 UIGlassContainerEffect 与 SwiftUI 相同的容器模式,保持一致性
小组件中的强调渲染模式 当用户选择色调主屏幕时,系统应用色调玻璃

最佳实践

  • 始终使用 GlassEffectContainer:当对多个同级视图应用玻璃效果时,它支持变形并提高渲染性能
  • 在其他外观修饰符之后应用 .glassEffect():如 frame、font、padding
  • 仅对响应用户交互的元素使用 .interactive():如按钮、可切换项
  • 在容器中仔细选择间距:以控制玻璃效果何时合并
  • 在更改视图层次结构时使用 withAnimation:以实现平滑的变形过渡
  • 在不同外观下测试:浅色模式、深色模式以及强调/色调模式
  • 确保无障碍对比度:玻璃上的文本必须保持可读性

应避免的反模式

  • 使用多个独立的 .glassEffect() 视图而不使用 GlassEffectContainer
  • 嵌套过多玻璃效果——会降低性能和视觉清晰度
  • 对每个视图都应用玻璃效果——仅保留给交互元素、工具栏和卡片
  • 在 UIKit 中使用圆角时忘记设置 clipsToBounds = true
  • 忽略小组件中的强调渲染模式——会破坏色调主屏幕的外观
  • 在玻璃后面使用不透明背景——会破坏半透明效果

何时使用

  • 采用新 iOS 26 设计的导航栏、工具栏和标签栏
  • 浮动操作按钮和卡片式容器
  • 需要视觉深度和触摸反馈的交互控件
  • 需要与系统液态玻璃外观集成的小组件
  • 相关 UI 状态之间的变形过渡