You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现SwiftUI菜单从圆形到椭圆形的联动位移动画?

SwiftUI图标堆叠展开动画实现方案

原代码问题

原代码通过if !hidden条件渲染左右图标,导致图标直接出现而非平滑位移;同时动画配置分散,无法实现堆叠→展开的连贯效果。

修改后的代码

import SwiftUI

struct ContentView: View {
    @State private var hidden = true
    
    var body: some View {
        HStack(spacing: 0) { // 初始间距为0,让图标堆叠
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundStyle(Color.black)
                .font(.system(size: 50))
                .offset(x: hidden ? 0 : -60) // 初始偏移0,展开后左移60
                .opacity(hidden ? 0 : 1)
            
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundStyle(Color.white)
                .font(.system(size: 50))
            
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundStyle(Color.yellow)
                .font(.system(size: 50))
                .offset(x: hidden ? 0 : 60) // 初始偏移0,展开后右移60
                .opacity(hidden ? 0 : 1)
        }
        .padding(.horizontal, hidden ? 10 : 30) // 初始内边距小,展开后增大
        .padding(.vertical, 5)
        .background(
            RoundedRectangle(cornerSize: CGSize(width: hidden ? 50 : 20, height: hidden ? 50 : 20))
                .fill(.red)
        )
        .onTapGesture {
            withAnimation(.easeInOut(duration: 0.5)) { // 统一动画时长和曲线
                hidden.toggle()
            }
        }
        .padding()
    }
}

#Preview {
    ContentView()
}

关键改动说明

  • 移除条件渲染:始终保留三个图标,通过offset和opacity控制状态,避免视图重建导致的突兀效果。
  • 位移控制:利用offset(x:)让左右图标在堆叠状态与展开状态间平滑移动,初始偏移为0(与中间图标重叠),展开时分别向左右偏移。
  • 统一动画:通过withAnimation包裹状态切换,让所有关联属性(偏移、透明度、内边距、圆角)同步执行动画,保证连贯效果。
  • 背景适配:调整圆角大小和HStack内边距,初始时背景呈现圆形,展开后随HStack宽度增加自然变为椭圆。

内容的提问来源于stack exchange,提问作者Duck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 13:31:17