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

SwiftUI如何实现分段选择器按钮间的指示条平滑移动动画

解决方案

核心问题在于原实现缺少两个关键配置:

  • 没有为状态变更添加动画触发上下文,matchedGeometryEffect的转场动画需要在动画块内修改状态才会生效
  • 非选中状态的按钮顶部没有和指示条等高的占位元素,会导致选中时按钮高度突变,打断平滑过渡效果

修改后的完整实现代码如下:

struct ContentView: View {
    enum PageItem: String, CaseIterable, Identifiable {
        case page1
        case page2

        var id: String { rawValue }

        var title: LocalizedStringKey {
            switch self {
            case .page1:
                return "Page 1"
            case .page2:
                return "Page 2"
            }
        }
    }

    @Namespace private var pagePickerAnimation
    @State private var selectedPage: PageItem = .page1

    var body: some View {
        HStack(spacing: 16) {
            ForEach(PageItem.allCases) { page in
                Button {
                    // 包裹动画块触发过渡效果
                    withAnimation(.easeInOut(duration: 0.2)) {
                        selectedPage = page
                    }
                } label: {
                    VStack(spacing: 0) { // 固定间距避免垂直偏移
                        // 所有按钮统一保留1px高度的条,选中态为实色,非选中态为透明占位
                        Group {
                            if page == selectedPage {
                                Rectangle()
                                    .fill(Color(.label))
                                    .matchedGeometryEffect(id: "pageIndicator", in: pagePickerAnimation)
                            } else {
                                Rectangle()
                                    .fill(.clear)
                            }
                        }
                        .frame(maxWidth: .infinity)
                        .frame(height: 1)
                        
                        Text(page.title)
                            .padding(.vertical, 8)
                            .padding(.horizontal, 12)
                    }
                    .contentShape(Rectangle())
                }
            }
        }
        .padding()
    }
}

该方案可直接扩展到更多按钮的场景,只需给PageItem枚举新增对应case即可,无需修改其他逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 09:42:03