如何让 iOS toolbar 按钮显隐时呈现 Liquid Glass 变形动画?
仅通过 if 插入或移除 ToolbarItem,不能保证出现演示视频中的 Liquid Glass 液滴变形动画。可以先为状态变化提供动画事务;如果需要明确控制玻璃的出现、消失或相互融合,可以使用自定义玻璃控件的公开 API。
为什么点击有效,显隐却没有变形?
按钮的按压反馈、导航切换时 toolbar 的变形,以及条件变化引起的按钮显隐,是不同的动画场景。Apple 在 WWDC25 的 SwiftUI 介绍中展示了导航切换时 toolbar 项目的变形,但这并不意味着任意条件插入都会触发相同效果。
原代码也没有显式提供动画事务。即使补上,系统 toolbar 也不一定会采用预期的玻璃过渡。所引用的官方资料没有提供强制原生 ToolbarItem 选择该效果的开关。
保留原生 toolbar 时,先检查动画事务
可以在承载 .toolbar 的视图上,针对 text.isEmpty 添加动画:
TextField("输入文本", text: $text)
.toolbar {
if !text.isEmpty {
ToolbarItem(placement: .topBarTrailing) {
Button {
text = ""
} label: {
Image(systemName: "trash")
}
.accessibilityLabel("清空文本")
}
}
}
.animation(.default, value: text.isEmpty)
这会为空与非空之间的切换提供动画事务,覆盖键盘输入和其他操作引起的变化。这是一个排查步骤,具体的 toolbar 过渡仍需在目标 iOS 版本上确认,不能保证触发液滴变形。
如果使用 withAnimation,应包住真正改变 text 的操作。只包住清空按钮的动作,无法覆盖其他来源的文本变化。
需要控制玻璃显隐时,使用自定义操作区
整个按钮组完全消失时,可以使用 .materialize。它会过渡玻璃材质并淡入内容,不需要匹配另一个玻璃形状;具体语义见 Apple 的 materialize 文档。
下面使用原生 Liquid Glass API 创建自定义操作区,位置由应用布局管理:
import SwiftUI
@available(iOS 26.0, *)
struct GlassActionsView: View {
@State private var text = ""
@Namespace private var glassNamespace
var body: some View {
VStack {
TextField("输入文本", text: $text)
.textFieldStyle(.roundedBorder)
GlassEffectContainer {
HStack {
Spacer()
if !text.isEmpty {
Button {
text = ""
} label: {
Image(systemName: "trash")
.frame(width: 44, height: 44)
}
.buttonStyle(.plain)
.accessibilityLabel("清空文本")
.glassEffect(.regular.interactive(), in: .circle)
.glassEffectID("trash", in: glassNamespace)
.glassEffectTransition(.materialize)
}
}
.frame(height: 44)
}
.animation(.default, value: text.isEmpty)
}
.padding()
}
}
这段代码控制自定义玻璃按钮,不会改变系统 .topBarTrailing 的内部动画。GlassEffectContainer 保持存在,条件分支负责插入或移除带玻璃效果的按钮。
如果需要按钮之间像液滴一样融合
使用同一个 GlassEffectContainer,为相关玻璃视图分别设置稳定的 glassEffectID(_:in:),再使用 .matchedGeometry 过渡。它会参考容器内附近玻璃形状的几何信息,匹配还取决于形状距离和容器的 spacing。Apple 的 matchedGeometry 文档说明了这一条件。
当整组按钮消失、没有其他玻璃形状保留时,不能期待它自动融合到不存在的目标;这种情况更适合 .materialize。不要为了融合效果额外放置没有功能的按钮。
这些自定义方式的组织方法见 Apple 的 自定义视图 Liquid Glass 指南。将 .glassEffectTransition 加到 toolbar 内的按钮上,也不能据此认定它能控制系统为 toolbar 管理的共享玻璃背景。
备注:内容仅供参考。
