You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

关于在SwiftUI中为尺寸变化的按钮集合添加液态玻璃动画(Liquid Glass Animation)的技术问询

关于在SwiftUI中为尺寸变化的按钮集合添加液态玻璃动画(Liquid Glass Animation)的技术问询

嘿,我懂你想要的那种液态玻璃质感的过渡效果——就是按钮集合在切换时像融化流动一样的平滑动画对吧?刚好可以用SwiftUI的几个原生特性来实现,咱们来调整你的代码一步步接近这个效果:

首先得明确,要做出这种效果的核心是两个点:一是让切换前后的按钮元素产生“关联过渡”,二是给容器加上玻璃态的背景并配合合适的动画曲线。你的现有代码只是做了简单的显隐动画,缺少这两个关键部分,所以质感会比较生硬。

调整后的完整代码

这里是修改好的代码,关键部分我都加了注释:

import SwiftUI

struct ContentView: View {
    @State var showAlternate = false
    // 定义命名空间,用来关联切换前后的视图元素
    @Namespace private var animationNamespace
    
    var body: some View {
        VStack {
            Button {
                showAlternate.toggle()
            } label: {
                Image(systemName: "arrow.clockwise")
                Text("Show alternate")
            }
        }
        .padding()
        .toolbar {
            ToolbarItemGroup(placement: .bottomBar) {
                Button { } label: {
                    Image(systemName: "gear")
                }
                
                Spacer()
                
                HStack(spacing: 20) {
                    // 第一个按钮位置:切换前后的按钮用同一个ID关联,实现几何过渡
                    if showAlternate {
                        Button { } label: {
                            Image(systemName: "figure.badminton")
                                .font(.title)
                        }
                        .matchedGeometryEffect(id: "firstButtonSlot", in: animationNamespace)
                    } else {
                        Button { } label: {
                            Image(systemName: "figure.kickboxing")
                                .font(.title)
                        }
                        .matchedGeometryEffect(id: "firstButtonSlot", in: animationNamespace)
                    }
                    
                    // 第二个按钮位置:同样用统一ID关联
                    if showAlternate {
                        Button { } label: {
                            Image(systemName: "figure.run.treadmill")
                                .font(.title)
                        }
                        .matchedGeometryEffect(id: "secondButtonSlot", in: animationNamespace)
                    } else {
                        Button { } label: {
                            Image(systemName: "figure.skateboarding")
                                .font(.title)
                        }
                        .matchedGeometryEffect(id: "secondButtonSlot", in: animationNamespace)
                    }
                }
                .padding(.horizontal, 16)
                .padding(.vertical, 8)
                // 添加强化玻璃质感的背景
                .background(.ultraThinMaterial)
                .cornerRadius(12)
                .shadow(color: .black.opacity(0.1), radius: 4, x: 0, y: 2)
                // 用弹性动画模拟液态流动的柔和感
                .animation(.interactiveSpring(response: 0.6, dampingFraction: 0.7, blendDuration: 0.7), value: showAlternate)
            }
        }
    }
}

#Preview {
    ContentView()
}

关键改动的说明

  • 几何匹配效果(matchedGeometryEffect:这是实现液态过渡的核心——给切换前后对应位置的按钮设置同一个ID和命名空间,SwiftUI就会把它们识别成同一个逻辑元素的不同状态,过渡时会自动做平滑的位置、尺寸变形,而不是生硬的显隐。
  • 玻璃态背景:用.ultraThinMaterial这个原生的玻璃态材质,配合圆角和轻微阴影,直接给按钮容器加上玻璃质感,动画时背景也会跟着平滑过渡,强化液态玻璃的视觉感受。
  • 自定义弹性动画:把默认的.default动画换成interactiveSpring,这种非线性的弹性动画比线性动画更接近液态流动的柔和感,你还可以调整responsedampingFraction这些参数来适配你想要的“粘稠度”。
  • 固定布局间距:给HStack设置固定的spacing,避免切换时容器宽度突然跳动,让整个过渡更稳定流畅。

如果你想追求更极致的液态扭曲效果,还可以尝试给按钮添加额外的scaleEffectrotationEffect动画,甚至自定义Shape来模拟边缘的融化变形,但上面的改动已经能达到大部分场景下的液态玻璃过渡效果啦。

内容来源于stack exchange

火山引擎 最新活动