Skip to content

使用matchedGeometryEffect实现指示器平滑移动

使用 matchedGeometryEffect 实现指示器平滑移动,让你的 SwiftUI 标签栏动画更上一层楼!🚀 准备好见证奇迹了吗?

理解 matchedGeometryEffect 的魔力

matchedGeometryEffect 就像一个魔法师,它能让两个视图之间实现无缝的动画过渡。✨ 它的核心在于 idnamespace。拥有相同 idnamespace 的视图,SwiftUI 会自动计算它们之间的位置和大小差异,并生成平滑的动画。

  • id: 唯一标识符,用于匹配两个视图。
  • namespace: 命名空间,用于区分不同的动画效果。

指示器动画的实现步骤

  1. 定义 namespace: 首先,你需要创建一个 Namespace 来管理你的动画。

    swift
    @Namespace private var animationNamespace
  2. 为标签添加 id: 为每个标签创建一个唯一的 id,通常可以使用标签的索引。

  3. matchedGeometryEffect 应用于指示器: 在指示器视图上使用 matchedGeometryEffect,将它的 id 设置为当前选中的标签的 idnamespace 设置为之前定义的 animationNamespace

    swift
    .matchedGeometryEffect(selectedTabIndex, in: animationNamespace)
  4. 调整指示器的位置和大小: 指示器的位置和大小应该与当前选中的标签相匹配。

代码示例

swift
import SwiftUI

struct TabBarView: View {
    @State private var selectedTabIndex = 0
    @Namespace private var animationNamespace

    let tabs = ["首页", "发现", "我的"]

    var body: some View {
        HStack {
            ForEach(0..<tabs.count, id: \.self) { index in
                Button {
                    selectedTabIndex = index
                } label: {
                    Text(tabs[index])
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 8)
                        .background(
                            ZStack {
                                if selectedTabIndex == index {
                                    RoundedRectangle(cornerRadius: 8)
                                        .fill(.blue.opacity(0.2))
                                        .matchedGeometryEffect(id: "tab_indicator", in: animationNamespace)
                                }
                            }
                        )
                }
            }
        }
        .padding()
    }
}

优化你的动画效果

  • 使用不同的动画曲线: 你可以通过 .animation() 修饰符来调整动画的曲线和时长,让动画更符合你的需求。例如,你可以使用 .spring() 来创建一个弹簧效果。
  • 添加阴影和渐变: 为了让指示器看起来更立体,你可以添加阴影和渐变效果。
  • 考虑性能: 复杂的动画可能会影响性能。尽量避免在动画中使用过于复杂的视图。

通过 matchedGeometryEffect,你可以轻松实现平滑的标签栏指示器动画,为你的 App 增添一份精致和专业感。🎉 动手试试吧,你会发现它比你想象的还要强大!💪

本站使用 VitePress 制作